]> Cypherpunks repositories - gostls13.git/commitdiff
ld: add NOPTRBSS for large, pointer-free uninitialized data
authorRuss Cox <rsc@golang.org>
Wed, 22 Feb 2012 03:08:42 +0000 (22:08 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 22 Feb 2012 03:08:42 +0000 (22:08 -0500)
cc: add #pragma textflag to set it
runtime: mark mheap to go into noptr-bss.
        remove special case in garbage collector

Remove the ARM from.flag field created by CL 5687044.
The DUPOK flag was already in p->reg, so keep using that.

Otherwise test/nilptr.go creates a very large binary.
Should fix the arm build.
Diagnosed by minux.ma; replacement for CL 5690044.

R=golang-dev, minux.ma, r
CC=golang-dev
https://golang.org/cl/5686060

26 files changed:
src/cmd/5a/lex.c
src/cmd/5c/swt.c
src/cmd/5c/txt.c
src/cmd/5g/gg.h
src/cmd/5g/gobj.c
src/cmd/5g/gsubr.c
src/cmd/5l/asm.c
src/cmd/5l/l.h
src/cmd/5l/obj.c
src/cmd/5l/span.c
src/cmd/6c/txt.c
src/cmd/6l/asm.c
src/cmd/6l/obj.c
src/cmd/8c/txt.c
src/cmd/8l/asm.c
src/cmd/cc/cc.h
src/cmd/cc/dcl.c
src/cmd/cc/dpchk.c
src/cmd/cc/lexbody
src/cmd/cc/macbody
src/cmd/ld/data.c
src/cmd/ld/lib.h
src/cmd/ld/symtab.c
src/libmach/5obj.c
src/pkg/runtime/malloc.goc
src/pkg/runtime/mgc0.c

index ab7e5228ecfe0808eed9d1c32a9b79db11f1a02f..4bef0219a2c5726caeb1f640eedba257a5e4142b 100644 (file)
@@ -491,7 +491,6 @@ zaddr(Gen *a, int s)
 
        Bputc(&obuf, a->type);
        Bputc(&obuf, a->reg);
-       Bputc(&obuf, 0); // flag
        Bputc(&obuf, s);
        Bputc(&obuf, a->name);
        switch(a->type) {
index 124a9710f56bba49a3d9d65be3b59a44a55f4a53..7268f9af26726ddf5ccaaccfec69c61af0e31eca 100644 (file)
@@ -564,10 +564,9 @@ zaddr(char *bp, Adr *a, int s)
 
        bp[0] = a->type;
        bp[1] = a->reg;
-       bp[2] = 0; // flag
-       bp[3] = s;
-       bp[4] = a->name;
-       bp += 5;
+       bp[2] = s;
+       bp[3] = a->name;
+       bp += 4;
        switch(a->type) {
        default:
                diag(Z, "unknown type %d in zaddr", a->type);
index 4de8908905ecc5bb391f29f76d59af7679700305..dea406eb92549d55af7dd0c91552a40560c3264d 100644 (file)
@@ -139,7 +139,9 @@ gclean(void)
                        continue;
                if(s->type == types[TENUM])
                        continue;
+               textflag = s->dataflag;
                gpseudo(AGLOBL, s, nodconst(s->type->width));
+               textflag = 0;
        }
        nextpc();
        p->as = AEND;
index 99b26075e53d7fcff9850e377a0832bab7ca8316..7dbf3beecd0ce75197fd702da3f7fcf5544b82a7 100644 (file)
@@ -27,7 +27,6 @@ struct        Addr
        uchar   reg;
        char pun;
        uchar   etype;
-       char    flag;
 };
 #define        A       ((Addr*)0)
 
index 1e0e96f1d137583854ed564c0ac2bd2d74c71dc3..b562ba888ba26115ccc0563a6a3f0e66bc42ba68 100644 (file)
@@ -93,7 +93,6 @@ zaddr(Biobuf *b, Addr *a, int s)
        default:
                Bputc(b, a->type);
                Bputc(b, a->reg);
-               Bputc(b, a->flag);
                Bputc(b, s);
                Bputc(b, a->name);
        }
index 387ebad355135b77ae1db009d4055c5b9e65c375..86f05fb32c52765e13ffdd2e32628d95cdf69bc5 100644 (file)
@@ -254,9 +254,9 @@ ggloblnod(Node *nam, int32 width)
        p->to.type = D_CONST;
        p->to.offset = width;
        if(nam->readonly)
-               p->from.flag = RODATA;
+               p->reg = RODATA;
        if(nam->type != T && !haspointers(nam->type))
-               p->from.flag |= NOPTR;
+               p->reg |= NOPTR;
 }
 
 void
@@ -273,7 +273,7 @@ ggloblsym(Sym *s, int32 width, int dupok)
        p->to.offset = width;
        if(dupok)
                p->reg = DUPOK;
-       p->from.flag |= RODATA;
+       p->reg |= RODATA;
 }
 
 int
index 4a4bfe12923a84c393ac5e866f83e6be6ef19402..5edc27011a8862f36b3ff80f33a3bed793c39d47 100644 (file)
@@ -75,6 +75,7 @@ enum {
        ElfStrPlt,
        ElfStrNoteNetbsdIdent,
        ElfStrNoPtrData,
+       ElfStrNoPtrBss,
        NElfStr
 };
 
@@ -168,6 +169,7 @@ doelf(void)
        elfstr[ElfStrNoPtrData] = addstring(shstrtab, ".noptrdata");
        elfstr[ElfStrData] = addstring(shstrtab, ".data");
        elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
+       elfstr[ElfStrNoPtrBss] = addstring(shstrtab, ".noptrbss");
        if(HEADTYPE == Hnetbsd)
                elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
        addstring(shstrtab, ".rodata");
@@ -1847,12 +1849,14 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
                        case STYPE:
                        case SSTRING:
                        case SGOSTRING:
+                       case SNOPTRDATA:
                                if(!s->reachable)
                                        continue;
                                put(s, s->name, 'D', s->value, s->size, s->version, s->gotype);
                                continue;
 
                        case SBSS:
+                       case SNOPTRBSS:
                                if(!s->reachable)
                                        continue;
                                put(s, s->name, 'B', s->value, s->size, s->version, s->gotype);
index 4abb6f2f50ec2a61cd0d6672e232ae7bb8c3a176..b1a48ded89c7b48bdd0292cee1c7b502274461b7 100644 (file)
@@ -76,7 +76,6 @@ struct        Adr
        uchar   index; // not used on arm, required by ld/go.c
        char    reg;
        char    name;
-       char    flag;
        int32   offset2; // argsize
        char    class;
        Sym*    gotype;
index 316a9a01b394cd80c9c484e3cf42f1eb6ff6d5d6..eb078511b61014e13aa30fa32b6c522ffbe662f4 100644 (file)
@@ -301,7 +301,6 @@ zaddr(Biobuf *f, Adr *a, Sym *h[])
 
        a->type = Bgetc(f);
        a->reg = Bgetc(f);
-       a->flag = Bgetc(f);
        c = Bgetc(f);
        if(c < 0 || c > NSYM){
                print("sym out of range: %d\n", c);
@@ -541,7 +540,7 @@ loop:
                        s->type = SBSS;
                        s->value = 0;
                }
-               if(s->type != SBSS && s->type != SNOPTRDATA && !s->dupok) {
+               if(s->type != SBSS && s->type != SNOPTRBSS && !s->dupok) {
                        diag("redefinition: %s\n%P", s->name, p);
                        s->type = SBSS;
                        s->value = 0;
@@ -550,10 +549,14 @@ loop:
                        s->size = p->to.offset;
                if(p->reg & DUPOK)
                        s->dupok = 1;
-               if(p->from.flag & RODATA)
+               if(p->reg & RODATA)
                        s->type = SRODATA;
-               else if(p->from.flag & NOPTR)
-                       s->type = SNOPTRDATA;
+               else if(p->reg & NOPTR) {
+                       if(s->np > 0)
+                               s->type = SNOPTRDATA;
+                       else
+                               s->type = SNOPTRBSS;
+               }
                break;
 
        case ADATA:
index 2e1232a1a164df7b905f8fdc6e6892838be62e42..13e1848e16047045f1d6d47011a667190f719fcf 100644 (file)
@@ -421,6 +421,8 @@ symaddr(Sym *s)
        case SDATA:
        case SBSS:
        case SCONST:
+       case SNOPTRDATA:
+       case SNOPTRBSS:
                break;
        }
        return v;
index dd232f085fdb24f3ab82bb5ed3253751f592c4a4..2cb8c158519b2efdf65bf054fd1361d54a0fd181 100644 (file)
@@ -158,7 +158,9 @@ gclean(void)
                        continue;
                if(s->type == types[TENUM])
                        continue;
+               textflag = s->dataflag;
                gpseudo(AGLOBL, s, nodconst(s->type->width));
+               textflag = 0;
        }
        nextpc();
        p->as = AEND;
index b64a6dabbc33f003943f37c24e3cb38413be9cf9..d5954ea517b8e211f7c5e90c9c8e967ba508de9b 100644 (file)
@@ -96,6 +96,7 @@ enum {
        ElfStrGnuVersionR,
        ElfStrNoteNetbsdIdent,
        ElfStrNoPtrData,
+       ElfStrNoPtrBss,
        NElfStr
 };
 
@@ -573,6 +574,7 @@ doelf(void)
        elfstr[ElfStrNoPtrData] = addstring(shstrtab, ".noptrdata");
        elfstr[ElfStrData] = addstring(shstrtab, ".data");
        elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
+       elfstr[ElfStrNoPtrBss] = addstring(shstrtab, ".noptrbss");
        if(HEADTYPE == Hnetbsd)
                elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
        addstring(shstrtab, ".elfdata");
@@ -1169,6 +1171,7 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
                case SCONST:
                case SRODATA:
                case SDATA:
+               case SNOPTRDATA:
                case SELFROSECT:
                case SMACHOGOT:
                case STYPE:
@@ -1181,6 +1184,7 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
                        continue;
 
                case SBSS:
+               case SNOPTRBSS:
                        if(!s->reachable)
                                continue;
                        put(s, s->name, 'B', symaddr(s), s->size, s->version, s->gotype);
index 19f85f059e139972b1eb210c43049675471ef14b..f441f3303d138f97a8470f749e043d86b75d2238 100644 (file)
@@ -555,7 +555,7 @@ loop:
                        s->type = SBSS;
                        s->size = 0;
                }
-               if(s->type != SBSS && s->type != SNOPTRDATA && !s->dupok) {
+               if(s->type != SBSS && s->type != SNOPTRBSS && !s->dupok) {
                        diag("%s: redefinition: %s in %s",
                                pn, s->name, TNAME);
                        s->type = SBSS;
@@ -567,8 +567,12 @@ loop:
                        s->dupok = 1;
                if(p->from.scale & RODATA)
                        s->type = SRODATA;
-               else if(p->from.scale & NOPTR)
-                       s->type = SNOPTRDATA;
+               else if(p->from.scale & NOPTR) {
+                       if(s->np > 0)
+                               s->type = SNOPTRDATA;
+                       else
+                               s->type = SNOPTRBSS;
+               }
                goto loop;
 
        case ADATA:
index 65c551ef6f7f3794dbc177ca2d694c271b8afc05..3a08da7cd2446f24d750f224273bc7cee4f0a7c5 100644 (file)
@@ -146,7 +146,9 @@ gclean(void)
                        continue;
                if(s->type == types[TENUM])
                        continue;
+               textflag = s->dataflag;
                gpseudo(AGLOBL, s, nodconst(s->type->width));
+               textflag = 0;
        }
        nextpc();
        p->as = AEND;
index 27881d80888bcb7e73d0c0f0a9a95da9764a7d27..2b8137fb3add316eba20def4c4e1a9aa76dcaa95 100644 (file)
@@ -92,6 +92,7 @@ enum {
        ElfStrGnuVersionR,
        ElfStrNoteNetbsdIdent,
        ElfStrNoPtrData,
+       ElfStrNoPtrBss,
        NElfStr
 };
 
@@ -530,6 +531,7 @@ doelf(void)
        elfstr[ElfStrNoPtrData] = addstring(shstrtab, ".noptrdata");
        elfstr[ElfStrData] = addstring(shstrtab, ".data");
        elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
+       elfstr[ElfStrNoPtrBss] = addstring(shstrtab, ".noptrbss");
        if(HEADTYPE == Hnetbsd)
                elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
        addstring(shstrtab, ".elfdata");
@@ -1256,12 +1258,14 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
                        case SSTRING:
                        case SGOSTRING:
                        case SWINDOWS:
+                       case SNOPTRDATA:
                                if(!s->reachable)
                                        continue;
                                put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
                                continue;
 
                        case SBSS:
+                       case SNOPTRBSS:
                                if(!s->reachable)
                                        continue;
                                put(s, s->name, 'B', symaddr(s), s->size, s->version, s->gotype);
index 566494e752adf8c941f0a6887f0d72eb1c582b08..f4632364cf0ec66e262e358137382c6b19e1ef52 100644 (file)
@@ -122,6 +122,7 @@ struct      Sym
        uchar   sym;
        uchar   aused;
        uchar   sig;
+       uchar   dataflag;
 };
 #define        S       ((Sym*)0)
 
@@ -524,6 +525,7 @@ EXTERN      int     nterm;
 EXTERN int     packflg;
 EXTERN int     fproundflg;
 EXTERN int     textflag;
+EXTERN int     dataflag;
 EXTERN int     ncontin;
 EXTERN int     canreach;
 EXTERN int     warnreach;
@@ -766,6 +768,7 @@ void        arginit(void);
 void   pragvararg(void);
 void   pragpack(void);
 void   pragfpround(void);
+void   pragdataflag(void);
 void   pragtextflag(void);
 void   pragincomplete(void);
 void   pragdynimport(void);
index d624bf2474daa1a1bb9891a476494a176d583c8e..a3ed9772da3a900722b34387d5a9d3c98959e626 100644 (file)
@@ -120,6 +120,10 @@ loop:
                (*f)(c, t, s);
                if(s->class == CLOCAL)
                        s = mkstatic(s);
+               if(dataflag) {
+                       s->dataflag = dataflag;
+                       dataflag = 0;
+               }
                firstbit = 0;
                n->sym = s;
                n->type = s->type;
index 084aa048460cd7c4a23112f31bce0e6d2f125fe6..c579e20d9805e5818eb676931573968043696935 100644 (file)
@@ -567,19 +567,23 @@ pragfpround(void)
 void
 pragtextflag(void)
 {
-       Sym *s;
-
-       textflag = 0;
-       s = getsym();
-       textflag = 7;
-       if(s)
-               textflag = atoi(s->name+1);
+       textflag = getnsn();
        while(getnsc() != '\n')
                ;
        if(debug['f'])
                print("%4d: textflag %d\n", lineno, textflag);
 }
 
+void
+pragdataflag(void)
+{
+       dataflag = getnsn();
+       while(getnsc() != '\n')
+               ;
+       if(debug['f'])
+               print("%4d: dataflag %d\n", lineno, dataflag);
+}
+
 void
 pragincomplete(void)
 {
index f4cc19c2ea4cae79e3a5acf41dfe41d801ab9fe9..d339cf9a29df2a04ec2bb99adf78a999c3e706eb 100644 (file)
@@ -74,6 +74,13 @@ pragtextflag(void)
                ;
 }
 
+void
+pragdataflag(void)
+{
+       while(getnsc() != '\n')
+               ;
+}
+
 void
 pragprofile(void)
 {
index ed66361f1a281f9359b16d218b706c7d2f69d4b5..874e82d25566a94cf52331678446b5944db429fc 100644 (file)
@@ -731,6 +731,10 @@ macprag(void)
                pragtextflag();
                return;
        }
+       if(s && strcmp(s->name, "dataflag") == 0) {
+               pragdataflag();
+               return;
+       }
        if(s && strcmp(s->name, "varargck") == 0) {
                pragvararg();
                return;
index e5e1db6d6e980d9a849f76ffe5e7b96e2107d83c..5ed8568ff3e07e2826f2a4a9322bc482958448c8 100644 (file)
@@ -806,8 +806,12 @@ dodata(void)
        }
 
        for(s = datap; s != nil; s = s->next) {
-               if(s->np > 0 && s->type == SBSS)
-                       s->type = SDATA;
+               if(s->np > 0) {
+                       if(s->type == SBSS)
+                               s->type = SDATA;
+                       if(s->type == SNOPTRBSS)
+                               s->type = SNOPTRDATA;
+               }
                if(s->np > s->size)
                        diag("%s: initialize bounds (%lld < %d)",
                                s->name, (vlong)s->size, s->np);
@@ -935,11 +939,24 @@ dodata(void)
                datsize += t;
        }
 
-       /* bss */
+       /* bss, then pointer-free bss */
+       noptr = nil;
        sect = addsection(&segdata, ".bss", 06);
        sect->vaddr = datsize;
-       for(; s != nil; s = s->next) {
-               if(s->type != SBSS) {
+       for(; ; s = s->next) {
+               if((s == nil || s->type >= SNOPTRBSS) && noptr == nil) {
+                       // finish bss, start noptrbss
+                       datsize = rnd(datsize, 8);
+                       sect->len = datsize - sect->vaddr;
+                       sect = addsection(&segdata, ".noptrbss", 06);
+                       sect->vaddr = datsize;
+                       noptr = sect;
+               }
+               if(s == nil) {
+                       sect->len = datsize - sect->vaddr;
+                       break;
+               }
+               if(s->type > SNOPTRBSS) {
                        cursym = s;
                        diag("unexpected symbol type %d", s->type);
                }
@@ -961,7 +978,6 @@ dodata(void)
                s->value = datsize;
                datsize += t;
        }
-       sect->len = datsize - sect->vaddr;
 }
 
 // assign addresses to text
@@ -1004,7 +1020,7 @@ textaddress(void)
 void
 address(void)
 {
-       Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr;
+       Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss;
        Sym *sym, *sub;
        uvlong va;
 
@@ -1031,6 +1047,8 @@ address(void)
                segdata.fileoff = segtext.fileoff + segtext.filelen;
        data = nil;
        noptr = nil;
+       bss = nil;
+       noptrbss = nil;
        for(s=segdata.sect; s != nil; s=s->next) {
                s->vaddr = va;
                va += s->len;
@@ -1040,8 +1058,12 @@ address(void)
                        data = s;
                if(strcmp(s->name, ".noptrdata") == 0)
                        noptr = s;
+               if(strcmp(s->name, ".bss") == 0)
+                       bss = s;
+               if(strcmp(s->name, ".noptrbss") == 0)
+                       noptrbss = s;
        }
-       segdata.filelen -= data->next->len; // deduct .bss
+       segdata.filelen -= bss->len + noptrbss->len; // deduct .bss
 
        text = segtext.sect;
        rodata = text->next;
@@ -1068,7 +1090,11 @@ address(void)
        xdefine("epclntab", SRODATA, pclntab->vaddr + pclntab->len);
        xdefine("noptrdata", SBSS, noptr->vaddr);
        xdefine("enoptrdata", SBSS, noptr->vaddr + noptr->len);
+       xdefine("bss", SBSS, bss->vaddr);
+       xdefine("ebss", SBSS, bss->vaddr + bss->len);
        xdefine("data", SBSS, data->vaddr);
        xdefine("edata", SBSS, data->vaddr + data->len);
+       xdefine("noptrbss", SBSS, noptrbss->vaddr);
+       xdefine("enoptrbss", SBSS, noptrbss->vaddr + noptrbss->len);
        xdefine("end", SBSS, segdata.vaddr + segdata.len);
 }
index a66a571c215da2c2143591480679fc1c8aa08e12..f5881b5d6f1bcffe4da746c4f5146051cdbf2498 100644 (file)
@@ -49,6 +49,7 @@ enum
        SMACHOGOT,
        SWINDOWS,
        SBSS,
+       SNOPTRBSS,
 
        SXREF,
        SMACHODYNSTR,
index d89359958e4139d1f9e7b769dc86bee045fa0ad5..6d76e9e775f75eec3a2ceced0b48716fbda14146 100644 (file)
@@ -334,6 +334,10 @@ symtab(void)
        xdefine("enoptrdata", SBSS, 0);
        xdefine("data", SBSS, 0);
        xdefine("edata", SBSS, 0);
+       xdefine("bss", SBSS, 0);
+       xdefine("ebss", SBSS, 0);
+       xdefine("noptrbss", SBSS, 0);
+       xdefine("enoptrbss", SBSS, 0);
        xdefine("end", SBSS, 0);
        xdefine("epclntab", SRODATA, 0);
        xdefine("esymtab", SRODATA, 0);
index a5827f55993ec9919875da9b2137d7b862047816..e539362b0b8f41e29572f31715d1ebd7e40fd5f5 100644 (file)
@@ -112,7 +112,7 @@ addr(Biobuf *bp)
        long off;
 
        a.type = Bgetc(bp);     /* a.type */
-       skip(bp,2);             /* reg, flag */
+       skip(bp,1);             /* reg */
        a.sym = Bgetc(bp);      /* sym index */
        a.name = Bgetc(bp);     /* sym type */
        switch(a.type){
index c9f1d67c22d3f432094297fce180c83b43b57847..932e3d9ef639fa1a2811ccc206adb1d79678c7d3 100644 (file)
@@ -14,7 +14,9 @@ package runtime
 #include "defs_GOOS_GOARCH.h"
 #include "type.h"
 
+#pragma dataflag 16 /* mark mheap as 'no pointers', hiding from garbage collector */
 MHeap runtime·mheap;
+
 extern MStats mstats;  // defined in extern.go
 
 extern volatile int32 runtime·MemProfileRate;
index 8efa7afc0324150926da81de6203f6335ada0e87..fd1babfd35d3287f4326a20919581374250cafad 100644 (file)
@@ -85,7 +85,7 @@ struct FinBlock
 
 extern byte data[];
 extern byte etext[];
-extern byte end[];
+extern byte ebss[];
 
 static G *fing;
 static FinBlock *finq; // list of finalizers that are to be executed
@@ -630,10 +630,7 @@ mark(void (*scan)(byte*, int64))
        FinBlock *fb;
 
        // mark data+bss.
-       // skip runtime·mheap itself, which has no interesting pointers
-       // and is mostly zeroed and would not otherwise be paged in.
-       scan(data, (byte*)&runtime·mheap - data);
-       scan((byte*)(&runtime·mheap+1), end - (byte*)(&runtime·mheap+1));
+       scan(data, ebss - data);
 
        // mark stacks
        for(gp=runtime·allg; gp!=nil; gp=gp->alllink) {