]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cc, cmd/ld, runtime: disallow conservative data/bss objects
authorRuss Cox <rsc@golang.org>
Wed, 24 Sep 2014 20:55:26 +0000 (16:55 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 24 Sep 2014 20:55:26 +0000 (16:55 -0400)
In linker, refuse to write conservative (array of pointers) as the
garbage collection type for any variable in the data/bss GC program.

In the linker, attach the Go type to an already-read C declaration
during dedup. This gives us Go types for C globals for free as long
as the cmd/dist-generated Go code contains the declaration.
(Most runtime C declarations have a corresponding Go declaration.
Both are bss declarations and so the linker dedups them.)

In cmd/dist, add a few more C files to the auto-Go-declaration list
in order to get Go type information for the C declarations into the linker.

In C compiler, mark all non-pointer-containing global declarations
and all string data as NOPTR. This allows them to exist in C files
without any corresponding Go declaration. Count C function pointers
as "non-pointer-containing", since we have no heap-allocated C functions.

In runtime, add NOPTR to the remaining pointer-containing declarations,
none of which refer to Go heap objects.

In runtime, also move os.Args and syscall.envs data into runtime-owned
variables. Otherwise, in programs that do not import os or syscall, the
runtime variables named os.Args and syscall.envs will be missing type
information.

I believe that this CL eliminates the final source of conservative GC scanning
in non-SWIG Go programs, and therefore...

Fixes #909.

LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/149770043

32 files changed:
src/cmd/cc/dcl.c
src/cmd/cc/lex.c
src/cmd/cgo/out.go
src/cmd/dist/buildruntime.c
src/cmd/ld/data.c
src/liblink/objfile.c
src/os/proc.go
src/runtime/asm_386.s
src/runtime/asm_amd64.s
src/runtime/asm_amd64p32.s
src/runtime/heapdump.c
src/runtime/malloc.c
src/runtime/malloc.h
src/runtime/mcache.c
src/runtime/mgc0.c
src/runtime/os_windows.c
src/runtime/proc.c
src/runtime/proc.go
src/runtime/runtime.c
src/runtime/runtime.go
src/runtime/signals_darwin.h
src/runtime/signals_dragonfly.h
src/runtime/signals_freebsd.h
src/runtime/signals_linux.h
src/runtime/signals_nacl.h
src/runtime/signals_netbsd.h
src/runtime/signals_openbsd.h
src/runtime/signals_plan9.h
src/runtime/signals_solaris.h
src/runtime/stack.c
src/runtime/thunk.s
src/syscall/env_unix.go

index 292717d688bcfdaf90d872141972487f65aa3609..117508fd6d943de7c6c010a9e22943fbe35da8af 100644 (file)
@@ -30,6 +30,9 @@
 
 #include <u.h>
 #include "cc.h"
+#include "../ld/textflag.h"
+
+static int haspointers(Type*);
 
 Node*
 dodecl(void (*f)(int,Type*,Sym*), int c, Type *t, Node *n)
@@ -123,7 +126,8 @@ loop:
                if(dataflag) {
                        s->dataflag = dataflag;
                        dataflag = 0;
-               }
+               } else if(s->type != T && !haspointers(s->type))
+                       s->dataflag = NOPTR;
                firstbit = 0;
                n->sym = s;
                n->type = s->type;
@@ -568,9 +572,8 @@ haspointers(Type *t)
                return 0;
        case TARRAY:
                return haspointers(t->link);
-       case TFUNC:
        case TIND:
-               return 1;
+               return t->link->etype != TFUNC;
        default:
                return 0;
        }
index 55fc36b1e098e4725f2ccb41b3b0366a9f66603c..7c9f718c09081103032dfaff2827d752cb5c552c 100644 (file)
@@ -31,6 +31,7 @@
 #include       <u.h>
 #include       "cc.h"
 #include       "y.tab.h"
+#include       "../ld/textflag.h"
 
 #ifndef        CPP
 #define        CPP     "cpp"
@@ -1317,6 +1318,7 @@ cinit(void)
        t->width = 0;
        symstring = slookup(".string");
        symstring->class = CSTATIC;
+       symstring->dataflag = NOPTR;
        symstring->type = t;
 
        t = typ(TARRAY, types[TCHAR]);
index 6586531ada3b6e0eea4ddb431e99e186f48b72e7..2d14f766fc4dae1ec5bad258022cb2a8f6cdc474 100644 (file)
@@ -129,6 +129,7 @@ func (p *Package) writeDefs() {
                        fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, n.Mangle)
                        fmt.Fprintf(&gccgoInit, "\t%s = %s%s;\n", n.Mangle, amp, n.C)
                } else {
+                       fmt.Fprintf(fc, "#pragma dataflag NOPTR /* C pointer, not heap pointer */ \n")
                        fmt.Fprintf(fc, "void *·%s = %s%s;\n", n.Mangle, amp, n.C)
                }
                fmt.Fprintf(fc, "\n")
@@ -397,6 +398,7 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
        // C wrapper calls into gcc, passing a pointer to the argument frame.
        fmt.Fprintf(fc, "#pragma cgo_import_static %s\n", cname)
        fmt.Fprintf(fc, "void %s(void*);\n", cname)
+       fmt.Fprintf(fc, "#pragma dataflag NOPTR\n")
        fmt.Fprintf(fc, "void *·%s = %s;\n", cname, cname)
 
        nret := 0
@@ -1151,20 +1153,31 @@ void *_CMalloc(size_t);
 const cProlog = `
 #include "runtime.h"
 #include "cgocall.h"
+#include "textflag.h"
 
+#pragma dataflag NOPTR
 static void *cgocall_errno = runtime·cgocall_errno;
+#pragma dataflag NOPTR
 void *·_cgo_runtime_cgocall_errno = &cgocall_errno;
 
+#pragma dataflag NOPTR
 static void *runtime_gostring = runtime·gostring;
+#pragma dataflag NOPTR
 void *·_cgo_runtime_gostring = &runtime_gostring;
 
+#pragma dataflag NOPTR
 static void *runtime_gostringn = runtime·gostringn;
+#pragma dataflag NOPTR
 void *·_cgo_runtime_gostringn = &runtime_gostringn;
 
+#pragma dataflag NOPTR
 static void *runtime_gobytes = runtime·gobytes;
+#pragma dataflag NOPTR
 void *·_cgo_runtime_gobytes = &runtime_gobytes;
 
+#pragma dataflag NOPTR
 static void *runtime_cmalloc = runtime·cmalloc;
+#pragma dataflag NOPTR
 void *·_cgo_runtime_cmalloc = &runtime_cmalloc;
 
 void ·_Cerrno(void*, int32);
index 1257d5b811b2b22395e6bef34451a579b6c36456..bb774e05fcf429a2aabcbe512de470647e82fd74 100644 (file)
@@ -330,9 +330,11 @@ mkzsys(char *dir, char *file)
 static char *runtimedefs[] = {
        "defs.c",
        "malloc.c",
+       "mcache.c",
        "mgc0.c",
        "proc.c",
        "parfor.c",
+       "stack.c",
 };
 
 // mkzruntimedefs writes zruntime_defs_$GOOS_$GOARCH.h,
index 71624c3304b73dcb644c6adfd0c0bf828494182f..9d224d9eb9016bfa41ef0a3267a49a0ee6f44767 100644 (file)
@@ -818,6 +818,7 @@ proggenaddsym(ProgGen *g, LSym *s)
 
        if(s->gotype == nil && s->size >= PtrSize) {
                // conservative scan
+               diag("missing Go type information for global symbol: %s", s->name);
                if((s->size%PtrSize) || (g->pos%PtrSize))
                        diag("proggenaddsym: unaligned conservative symbol %s: size=%lld pos=%lld",
                                s->name, s->size, g->pos);
index 9b1e1b7a8fd244056bff622adcf62097f35ee3c8..15d602df928f3d348a9193245d61b4c15dcbce80 100644 (file)
@@ -550,7 +550,7 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn)
        static int ndup;
        char *name;
        Reloc *r;
-       LSym *s, *dup;
+       LSym *s, *dup, *typ;
        Pcln *pc;
        Auto *a;
        
@@ -586,7 +586,9 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn)
        s->type = t;
        if(s->size < size)
                s->size = size;
-       s->gotype = rdsym(ctxt, f, pkg);
+       typ = rdsym(ctxt, f, pkg);
+       if(typ != nil) // if bss sym defined multiple times, take type from any one def
+               s->gotype = typ;
        rddata(f, &s->p, &s->np);
        s->maxp = s->np;
        n = rdint(f);
index 38c436ec54d2450e6125be36d4ae243d602d1153..b63c85ad9071490f06f819c3bbd649fbd46fe60e 100644 (file)
@@ -11,6 +11,12 @@ import "syscall"
 // Args hold the command-line arguments, starting with the program name.
 var Args []string
 
+func init() {
+       Args = runtime_args()
+}
+
+func runtime_args() []string // in package runtime
+
 // Getuid returns the numeric user id of the caller.
 func Getuid() int { return syscall.Getuid() }
 
index 2961f10f2ab49a55ddaedc17512a01bd767ad963..846a214d555696dd4224ae7a72edb556bb2d5d98 100644 (file)
@@ -903,8 +903,6 @@ TEXT runtime·emptyfunc(SB),0,$0-0
 TEXT runtime·abort(SB),NOSPLIT,$0-0
        INT $0x3
 
-GLOBL runtime·tls0(SB), $32
-
 // hash function using AES hardware instructions
 TEXT runtime·aeshash(SB),NOSPLIT,$0-16
        MOVL    p+0(FP), AX     // ptr to data
index 44159bb57e6c79444043621ea28a2056a3b8eca5..7304d79a2fe35e3692d9ebca3ad0111ab7d84246 100644 (file)
@@ -871,8 +871,6 @@ TEXT runtime·gocputicks(SB),NOSPLIT,$0-8
        MOVQ    AX, ret+0(FP)
        RET
 
-GLOBL runtime·tls0(SB), $64
-
 // hash function using AES hardware instructions
 TEXT runtime·aeshash(SB),NOSPLIT,$0-32
        MOVQ    p+0(FP), AX     // ptr to data
index bbbd886a53a036d63c7e4e5f2648a24ff3fe1546..13a16425680fa449aea8e1686b415a2a2618a207 100644 (file)
@@ -674,8 +674,6 @@ TEXT runtime·gocputicks(SB),NOSPLIT,$0-8
        MOVQ    AX, ret+0(FP)
        RET
 
-GLOBL runtime·tls0(SB), $64
-
 // hash function using AES hardware instructions
 // For now, our one amd64p32 system (NaCl) does not
 // support using AES instructions, so have not bothered to
index 75897c3d353272be5488760b2efb4a5d82e6810c..54b9666b55cfddbd0b442aef2b5de96f207aba15 100644 (file)
@@ -59,6 +59,8 @@ static BitVector makeheapobjbv(byte *p, uintptr size);
 
 // fd to write the dump to.
 static uintptr dumpfd;
+
+#pragma dataflag NOPTR /* tmpbuf not a heap pointer at least */
 static byte    *tmpbuf;
 static uintptr tmpbufsize;
 
@@ -109,6 +111,7 @@ typedef struct TypeCacheBucket TypeCacheBucket;
 struct TypeCacheBucket {
        Type *t[TypeCacheAssoc];
 };
+#pragma dataflag NOPTR /* only initialized and used while world is stopped */
 static TypeCacheBucket typecache[TypeCacheBuckets];
 
 // dump a uint64 in a varint format parseable by encoding/binary
index 60d20a992deeb4e6ea515f4fdea46cc92101fd2f..b79c30b72049a38aa6b5b81ce7a7705a53f2f171 100644 (file)
@@ -329,29 +329,6 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n)
        return p;
 }
 
-// Runtime stubs.
-
-static void*
-cnew(Type *typ, intgo n)
-{
-       if(n < 0 || (typ->size > 0 && n > MaxMem/typ->size))
-               runtime·throw("runtime: allocation size out of range");
-       return runtime·mallocgc(typ->size*n, typ, typ->kind&KindNoPointers ? FlagNoScan : 0);
-}
-
-// same as runtime·new, but callable from C
-void*
-runtime·cnew(Type *typ)
-{
-       return cnew(typ, 1);
-}
-
-void*
-runtime·cnewarray(Type *typ, intgo n)
-{
-       return cnew(typ, n);
-}
-
 void
 runtime·setFinalizer_m(void)
 {
index 410a0071739ecdeb5fae706fd6bf6eb4f2ddd49b..b90f1baf29372ea8f662514f64bfb3c60d53152d 100644 (file)
@@ -526,8 +526,6 @@ uintptr     runtime·sweepone(void);
 void   runtime·markspan(void *v, uintptr size, uintptr n, bool leftover);
 void   runtime·unmarkspan(void *v, uintptr size);
 void   runtime·purgecachedstats(MCache*);
-void*  runtime·cnew(Type*);
-void*  runtime·cnewarray(Type*, intgo);
 void   runtime·tracealloc(void*, uintptr, Type*);
 void   runtime·tracefree(void*, uintptr);
 void   runtime·tracegc(void);
index 17ea5d2e26c8ece0ad0e7450291f5bc6e13bf7fa..5fdbe32667781af9be6e05079919031fb849b30a 100644 (file)
@@ -13,7 +13,7 @@
 extern volatile intgo runtime·MemProfileRate;
 
 // dummy MSpan that contains no free objects.
-static MSpan runtime·emptymspan;
+MSpan runtime·emptymspan;
 
 MCache*
 runtime·allocmcache(void)
index 54728d5ada0c1a48dff7efb42e5ad4c2755ca0a8..c92fa1db73a3e5b6dab76bb4cae26fe631e2ee81 100644 (file)
@@ -120,7 +120,7 @@ FinBlock*   runtime·finc;  // cache of free blocks
 static byte finptrmask[FinBlockSize/PtrSize/PointersPerByte];
 bool   runtime·fingwait;
 bool   runtime·fingwake;
-static FinBlock        *runtime·allfin;       // list of all blocks
+FinBlock       *runtime·allfin;       // list of all blocks
 
 BitVector      runtime·gcdatamask;
 BitVector      runtime·gcbssmask;
@@ -140,7 +140,7 @@ static BitVector    unrollglobgcprog(byte *prog, uintptr size);
 void runtime·bgsweep(void);
 static FuncVal bgsweepv = {runtime·bgsweep};
 
-static struct {
+struct {
        uint64  full;  // lock-free list of full blocks
        uint64  empty; // lock-free list of empty blocks
        byte    pad0[CacheLineSize]; // prevents false-sharing between full/empty and nproc/nwait
@@ -1038,7 +1038,6 @@ runtime·MSpan_Sweep(MSpan *s, bool preserve)
 
 // State of background runtime·sweep.
 // Protected by runtime·gclock.
-// Must match mgc0.go.
 struct
 {
        G*      g;
index 62d94b65a02061f333531cc6cef2e622498aa34a..6546d51d3350b0af11243f4d1392ed0a9d955188 100644 (file)
@@ -147,7 +147,7 @@ runtime·get_random_data(byte **rnd, int32 *rnd_len)
 void
 runtime·goenvs(void)
 {
-       extern Slice syscall·envs;
+       extern Slice runtime·envs;
 
        uint16 *env;
        String *s;
@@ -160,8 +160,8 @@ runtime·goenvs(void)
        for(p=env; *p; n++)
                p += runtime·findnullw(p)+1;
 
-       syscall·envs = runtime·makeStringSlice(n);
-       s = (String*)syscall·envs.array;
+       runtime·envs = runtime·makeStringSlice(n);
+       s = (String*)runtime·envs.array;
 
        p = env;
        for(i=0; i<n; i++) {
index 564798be7bbc692031fc06bbae66d9f91909f4ed..1f0a79098b2d4246d371bea3780a51d68c6e03f2 100644 (file)
@@ -102,9 +102,9 @@ extern String runtime·buildVersion;
 #pragma cgo_export_static main
 
 // Filled in by dynamic linker when Cgo is available.
-void* _cgo_init;
-void* _cgo_malloc;
-void* _cgo_free;
+void (*_cgo_init)(void);
+void (*_cgo_malloc)(void);
+void (*_cgo_free)(void);
 
 // Copy for Go code.
 void* runtime·cgoMalloc;
@@ -852,24 +852,19 @@ struct CgoThreadStart
        void (*fn)(void);
 };
 
+M *runtime·newM(void); // in proc.go
+
 // Allocate a new m unassociated with any thread.
 // Can use p for allocation context if needed.
 M*
 runtime·allocm(P *p)
 {
        M *mp;
-       static Type *mtype;  // The Go type M
 
        g->m->locks++;  // disable GC because it can be called from sysmon
        if(g->m->p == nil)
                acquirep(p);  // temporarily borrow p for mallocs in this function
-       if(mtype == nil) {
-               Eface e;
-               runtime·gc_m_ptr(&e);
-               mtype = ((PtrType*)e.type)->elem;
-       }
-
-       mp = runtime·cnew(mtype);
+       mp = runtime·newM();
        mcommoninit(mp);
 
        // In case of cgo or Solaris, pthread_create will make us a stack.
@@ -889,19 +884,12 @@ runtime·allocm(P *p)
        return mp;
 }
 
+G *runtime·newG(void); // in proc.go
+
 static G*
 allocg(void)
 {
-       G *gp;
-       static Type *gtype;
-       
-       if(gtype == nil) {
-               Eface e;
-               runtime·gc_g_ptr(&e);
-               gtype = ((PtrType*)e.type)->elem;
-       }
-       gp = runtime·cnew(gtype);
-       return gp;
+       return runtime·newG();
 }
 
 static M* lockextra(bool nilokay);
index 9b958685949ee2b977545bd9fe615c987c74bce5..4bb661b54b8c0b2c232cde9e370f6b5ee47a4cd1 100644 (file)
@@ -202,6 +202,14 @@ func newP() *p {
        return new(p)
 }
 
+func newM() *m {
+       return new(m)
+}
+
+func newG() *g {
+       return new(g)
+}
+
 func allgadd(gp *g) {
        if readgstatus(gp) == _Gidle {
                gothrow("allgadd: bad status Gidle")
index aa8dd8f7a008217172e81bcfcf7343ac23f48721..b3503fb909a2777fbddf3bee15d9e02783f277c9 100644 (file)
@@ -62,10 +62,12 @@ runtime·mchr(byte *p, byte c, byte *ep)
 }
 
 static int32   argc;
+
+#pragma dataflag NOPTR /* argv not a heap pointer */
 static uint8** argv;
 
-Slice os·Args;
-Slice syscall·envs;
+extern Slice runtime·argslice;
+extern Slice runtime·envs;
 
 void (*runtime·sysargs)(int32, uint8**);
 
@@ -97,8 +99,8 @@ runtime·goargs(void)
        if(Windows)
                return;
 
-       os·Args = runtime·makeStringSlice(argc);
-       s = (String*)os·Args.array;
+       runtime·argslice = runtime·makeStringSlice(argc);
+       s = (String*)runtime·argslice.array;
        for(i=0; i<argc; i++)
                s[i] = runtime·gostringnocopy(argv[i]);
 }
@@ -112,8 +114,8 @@ runtime·goenvs_unix(void)
        for(n=0; argv[argc+1+n] != 0; n++)
                ;
 
-       syscall·envs = runtime·makeStringSlice(n);
-       s = (String*)syscall·envs.array;
+       runtime·envs = runtime·makeStringSlice(n);
+       s = (String*)runtime·envs.array;
        for(i=0; i<n; i++)
                s[i] = runtime·gostringnocopy(argv[argc+1+i]);
 }
@@ -122,7 +124,7 @@ runtime·goenvs_unix(void)
 Slice
 runtime·environ()
 {
-       return syscall·envs;
+       return runtime·envs;
 }
 
 int32
@@ -267,10 +269,15 @@ runtime·check(void)
 #pragma dataflag NOPTR
 DebugVars      runtime·debug;
 
-static struct {
+typedef struct DbgVar DbgVar;
+struct DbgVar
+{
        int8*   name;
        int32*  value;
-} dbgvar[] = {
+};
+
+#pragma dataflag NOPTR /* dbgvar has no heap pointers */
+static DbgVar dbgvar[] = {
        {"allocfreetrace", &runtime·debug.allocfreetrace},
        {"efence", &runtime·debug.efence},
        {"gctrace", &runtime·debug.gctrace},
index dbaea45a66216fce84aac5a61f8160cd22ffea70..4e4e1d17a5c3da3e2c3c1232876a074672d19b7d 100644 (file)
@@ -9,6 +9,8 @@ var ticks struct {
        val  uint64
 }
 
+var tls0 [8]uintptr // available storage for m0's TLS; not necessarily used; opaque to GC
+
 // Note: Called by runtime/pprof in addition to runtime code.
 func tickspersecond() int64 {
        r := int64(atomicload64(&ticks.val))
@@ -47,3 +49,12 @@ func parforalloc(nthrmax uint32) *parfor {
                nthrmax: nthrmax,
        }
 }
+
+var envs []string
+var argslice []string
+
+// called from syscall
+func runtime_envs() []string { return envs }
+
+// called from os
+func runtime_args() []string { return argslice }
index 229b585902565f4445d32a0d21980287545301ff..8761e1bd943e9a20b03813c89b4d7c4aa8a07f3f 100644 (file)
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include "textflag.h"
+
 #define N SigNotify
 #define K SigKill
 #define T SigThrow
 #define P SigPanic
 #define D SigDefault
 
+#pragma dataflag NOPTR
 SigTab runtime·sigtab[] = {
        /* 0 */ 0, "SIGNONE: no trap",
        /* 1 */ N+K, "SIGHUP: terminal line hangup",
index 4d27e050d089de91e83ba4b399d4254d60435716..07343a766e8d9f12202df7d5d9e37db7a7480575 100644 (file)
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include "textflag.h"
+
 #define N SigNotify
 #define K SigKill
 #define T SigThrow
 #define P SigPanic
 #define D SigDefault
 
+#pragma dataflag NOPTR
 SigTab runtime·sigtab[] = {
        /* 0 */ 0, "SIGNONE: no trap",
        /* 1 */ N+K, "SIGHUP: terminal line hangup",
index 8d45c50c3b1f1a8a7075c493e49b200bc5684227..39e0a947e026baded93075af1e9c97b8c7e1d516 100644 (file)
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include "textflag.h"
+
 #define N SigNotify
 #define K SigKill
 #define T SigThrow
 #define P SigPanic
 #define D SigDefault
 
+#pragma dataflag NOPTR
 SigTab runtime·sigtab[] = {
        /* 0 */ 0, "SIGNONE: no trap",
        /* 1 */ N+K, "SIGHUP: terminal line hangup",
index 368afc1c841b267d46e1f7fdfb7470cee2b43874..374107609fcb61428e2b043472252684f9c3b9a7 100644 (file)
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include "textflag.h"
+
 #define N SigNotify
 #define K SigKill
 #define T SigThrow
 #define P SigPanic
 #define D SigDefault
 
+#pragma dataflag NOPTR
 SigTab runtime·sigtab[] = {
        /* 0 */ 0, "SIGNONE: no trap",
        /* 1 */ N+K, "SIGHUP: terminal line hangup",
index 229b585902565f4445d32a0d21980287545301ff..8761e1bd943e9a20b03813c89b4d7c4aa8a07f3f 100644 (file)
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include "textflag.h"
+
 #define N SigNotify
 #define K SigKill
 #define T SigThrow
 #define P SigPanic
 #define D SigDefault
 
+#pragma dataflag NOPTR
 SigTab runtime·sigtab[] = {
        /* 0 */ 0, "SIGNONE: no trap",
        /* 1 */ N+K, "SIGHUP: terminal line hangup",
index 7140de86fcfc3bb9c777dfd8f8c21b3566a5120d..950a2fe62c2d06098341a706e844e8c97ea05e4d 100644 (file)
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include "textflag.h"
+
 #define N SigNotify
 #define K SigKill
 #define T SigThrow
 #define P SigPanic
 #define D SigDefault
 
+#pragma dataflag NOPTR
 SigTab runtime·sigtab[] = {
        /*  0 */        0, "SIGNONE: no trap",
        /*  1 */        N+K, "SIGHUP: terminal line hangup",
index 7140de86fcfc3bb9c777dfd8f8c21b3566a5120d..950a2fe62c2d06098341a706e844e8c97ea05e4d 100644 (file)
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include "textflag.h"
+
 #define N SigNotify
 #define K SigKill
 #define T SigThrow
 #define P SigPanic
 #define D SigDefault
 
+#pragma dataflag NOPTR
 SigTab runtime·sigtab[] = {
        /*  0 */        0, "SIGNONE: no trap",
        /*  1 */        N+K, "SIGHUP: terminal line hangup",
index 818f508cf3b4ee064960c7a2c3c2fd72d4529b11..4ee8e542c901fc511bbda89a2e4a8a1ff05ac1d2 100644 (file)
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include "textflag.h"
+
 #define N SigNotify
 #define K SigKill
 #define T SigThrow
@@ -16,6 +18,7 @@
 // If you add entries to this table, you must respect the prefix ordering
 // and also update the constant values is os_plan9.h.
 
+#pragma dataflag NOPTR
 SigTab runtime·sigtab[] = {
        // Traps that we cannot be recovered.
        T,      "sys: trap: debug exception",
index c272cad2928dd81650fb63f8c3950019079ed04b..1f0a65ea620fabac1f1bf8422b6c182909d73035 100644 (file)
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include "textflag.h"
+
 #define N SigNotify
 #define K SigKill
 #define T SigThrow
 #define P SigPanic
 #define D SigDefault
 
+#pragma dataflag NOPTR
 SigTab runtime·sigtab[] = {
        /* 0 */         0, "SIGNONE: no trap",
        /* 1 */         N+K, "SIGHUP: hangup",
index 6fbab8fb6ee5fc1ff04ee57bd7eb8eea5702075e..0d8814731c5d6b202255b69a0a13935c0d04526d 100644 (file)
@@ -32,8 +32,8 @@ enum
 // Stacks are assigned an order according to size.
 //     order = log_2(size/FixedStack)
 // There is a free list for each order.
-static MSpan runtime·stackpool[NumStackOrders];
-static Mutex runtime·stackpoolmu;
+MSpan runtime·stackpool[NumStackOrders];
+Mutex runtime·stackpoolmu;
 // TODO: one lock per order?
 
 void
index 5e8e674f548bf6834a6326ea4b7796fce328874f..d6a2d399e6c136fe9581c41479a744a2e4f9e235 100644 (file)
@@ -164,7 +164,7 @@ TEXT runtime·main_init(SB),NOSPLIT,$0-0
 TEXT runtime·main_main(SB),NOSPLIT,$0-0
        JMP     main·main(SB)
 
-TEXT runtime·timenow(SB), NOSPLIT, $0-0
+TEXT runtime·timenow(SB),NOSPLIT,$0-0
        JMP     time·now(SB)
 
 TEXT sync∕atomic·runtime_procPin(SB),NOSPLIT,$0-0
@@ -172,3 +172,9 @@ TEXT sync∕atomic·runtime_procPin(SB),NOSPLIT,$0-0
 
 TEXT sync∕atomic·runtime_procUnpin(SB),NOSPLIT,$0-0
        JMP     sync·runtime_procUnpin(SB)
+
+TEXT syscall·runtime_envs(SB),NOSPLIT,$0-0
+       JMP     runtime·runtime_envs(SB)
+
+TEXT os·runtime_args(SB),NOSPLIT,$0-0
+       JMP     runtime·runtime_args(SB)
index ad354ed05785cfcdc5ee6230930667a16a26ea12..01ac38af13ced11cd829eb94ee1c454d2bcf829c 100644 (file)
@@ -22,9 +22,11 @@ var (
 
        // envs is provided by the runtime. elements are expected to be
        // of the form "key=value".
-       envs []string
+       envs []string = runtime_envs()
 )
 
+func runtime_envs() []string // in package runtime
+
 // setenv_c is provided by the runtime, but is a no-op if cgo isn't
 // loaded.
 func setenv_c(k, v string)