From 193daab9889708f7a20ff46efe0fa4b2bf0468d3 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 24 Sep 2014 16:55:26 -0400 Subject: cmd/cc, cmd/ld, runtime: disallow conservative data/bss objects 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 --- src/cmd/ld/data.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd/ld/data.c') diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c index 71624c3304..9d224d9eb9 100644 --- a/src/cmd/ld/data.c +++ b/src/cmd/ld/data.c @@ -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); -- cgit v1.3-5-g9baa From 117a6973cb17d45c0c14cd8fb576f5a06b0d7234 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 24 Sep 2014 14:45:11 -0700 Subject: build: fix elf builds Corrections due to new strict type rules for data+bss. Also disable misc/cgo/cdefstest since you can't compile C code anymore. TBR=iant CC=golang-codereviews https://golang.org/cl/148050044 --- include/link.h | 2 +- src/cmd/ld/data.c | 13 ++++++++++--- src/cmd/ld/lib.c | 4 +++- src/run.bash | 11 +++++++---- src/runtime/vdso_linux_amd64.c | 9 +++++++-- 5 files changed, 28 insertions(+), 11 deletions(-) (limited to 'src/cmd/ld/data.c') diff --git a/include/link.h b/include/link.h index 292b077394..845f9338d9 100644 --- a/include/link.h +++ b/include/link.h @@ -204,10 +204,10 @@ enum SELFSECT, SMACHO, /* Mach-O __nl_symbol_ptr */ SMACHOGOT, + SWINDOWS, SNOPTRDATA, SINITARR, SDATA, - SWINDOWS, SBSS, SNOPTRBSS, STLSBSS, diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c index 9d224d9eb9..89226bfe28 100644 --- a/src/cmd/ld/data.c +++ b/src/cmd/ld/data.c @@ -625,6 +625,7 @@ addstrdata(char *name, char *value) sp = linklookup(ctxt, p, 0); free(p); addstring(sp, value); + sp->type = SRODATA; s = linklookup(ctxt, name, 0); s->size = 0; @@ -816,9 +817,15 @@ proggenaddsym(ProgGen *g, LSym *s) proggenskip(g, g->pos, s->value - g->pos); g->pos += s->value - g->pos; - if(s->gotype == nil && s->size >= PtrSize) { + // The test for names beginning with . here is meant + // to keep .dynamic and .dynsym from turning up as + // conservative symbols. They should be marked SELFSECT + // and not SDATA, but sometimes that doesn't happen. + // Leave debugging the SDATA issue for the Go rewrite. + + if(s->gotype == nil && s->size >= PtrSize && s->name[0] != '.') { // conservative scan - diag("missing Go type information for global symbol: %s", s->name); + diag("missing Go type information for global symbol: %s size %d", s->name, (int)s->size); if((s->size%PtrSize) || (g->pos%PtrSize)) diag("proggenaddsym: unaligned conservative symbol %s: size=%lld pos=%lld", s->name, s->size, g->pos); @@ -834,7 +841,7 @@ proggenaddsym(ProgGen *g, LSym *s) proggenarrayend(g); } g->pos = s->value + size; - } else if(s->gotype == nil || decodetype_noptr(s->gotype) || s->size < PtrSize) { + } else if(s->gotype == nil || decodetype_noptr(s->gotype) || s->size < PtrSize || s->name[0] == '.') { // no scan if(s->size < 32*PtrSize) { // Emit small symbols as data. diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c index 36f0f99de2..3edf7253d4 100644 --- a/src/cmd/ld/lib.c +++ b/src/cmd/ld/lib.c @@ -221,8 +221,10 @@ loadlib(void) // Provided by the code that imports the package. // Since we are simulating the import, we have to provide this string. cgostrsym = "go.string.\"runtime/cgo\""; - if(linkrlookup(ctxt, cgostrsym, 0) == nil) + if(linkrlookup(ctxt, cgostrsym, 0) == nil) { addstrdata(cgostrsym, "runtime/cgo"); + linklookup(ctxt, cgostrsym, 0)->type = SRODATA; + } } if(linkmode == LinkAuto) { diff --git a/src/run.bash b/src/run.bash index 4966cf1aa6..3c9430c87e 100755 --- a/src/run.bash +++ b/src/run.bash @@ -167,10 +167,13 @@ esac # This tests cgo -cdefs. That mode is not supported, # so it's okay if it doesn't work on some systems. # In particular, it works badly with clang on OS X. -[ "$CGO_ENABLED" != 1 ] || [ "$GOOS" == darwin ] || -(xcd ../misc/cgo/testcdefs -./test.bash || exit 1 -) || exit $? +# It doesn't work at all now that we disallow C code +# outside runtime. Once runtime has no C code it won't +# even be necessary. +# [ "$CGO_ENABLED" != 1 ] || [ "$GOOS" == darwin ] || +# (xcd ../misc/cgo/testcdefs +# ./test.bash || exit 1 +# ) || exit $? [ "$CGO_ENABLED" != 1 ] || [ "$GOOS" == darwin ] || (xcd ../misc/cgo/testgodefs diff --git a/src/runtime/vdso_linux_amd64.c b/src/runtime/vdso_linux_amd64.c index 38e1152438..41a41fdd6a 100644 --- a/src/runtime/vdso_linux_amd64.c +++ b/src/runtime/vdso_linux_amd64.c @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. #include "runtime.h" +#include "textflag.h" // Look up symbols in the Linux vDSO. @@ -171,14 +172,18 @@ struct vdso_info { Elf64_Verdef *verdef; }; +#pragma dataflag NOPTR static version_key linux26 = { (byte*)"LINUX_2.6", 0x3ae75f6 }; // initialize with vsyscall fallbacks +#pragma dataflag NOPTR void* runtime·__vdso_time_sym = (void*)0xffffffffff600400ULL; +#pragma dataflag NOPTR void* runtime·__vdso_gettimeofday_sym = (void*)0xffffffffff600000ULL; +#pragma dataflag NOPTR void* runtime·__vdso_clock_gettime_sym = (void*)0; -#define SYM_KEYS_COUNT 3 +#pragma dataflag NOPTR static symbol_key sym_keys[] = { { (byte*)"__vdso_time", 0xa33c485, &runtime·__vdso_time_sym }, { (byte*)"__vdso_gettimeofday", 0x315ca59, &runtime·__vdso_gettimeofday_sym }, @@ -301,7 +306,7 @@ vdso_parse_symbols(struct vdso_info *vdso_info, int32 version) if(vdso_info->valid == false) return; - for(i=0; ibucket[sym_keys[i].sym_hash % vdso_info->nbucket]; chain != 0; chain = vdso_info->chain[chain]) { -- cgit v1.3-5-g9baa From f6fc14094a476d2e23722f124cfcd8204c2659b0 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sun, 28 Sep 2014 08:27:05 -0700 Subject: cmd/ld: don't automatically mark symbols created by -X as reachable This fixes the bug in which the linker reports "missing Go type information" when a -X option refers to a symbol that is not used. Fixes #8821. LGTM=rsc R=rsc, r CC=golang-codereviews https://golang.org/cl/151000043 --- src/cmd/ld/data.c | 9 +++++++-- src/cmd/ld/lib.c | 4 +++- test/linkx.go | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'src/cmd/ld/data.c') diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c index 89226bfe28..9983a9281c 100644 --- a/src/cmd/ld/data.c +++ b/src/cmd/ld/data.c @@ -620,6 +620,7 @@ addstrdata(char *name, char *value) { LSym *s, *sp; char *p; + uchar reachable; p = smprint("%s.str", name); sp = linklookup(ctxt, p, 0); @@ -630,13 +631,17 @@ addstrdata(char *name, char *value) s = linklookup(ctxt, name, 0); s->size = 0; s->dupok = 1; + reachable = s->reachable; addaddr(ctxt, s, sp); adduint32(ctxt, s, strlen(value)); if(PtrSize == 8) adduint32(ctxt, s, 0); // round struct to pointer width - // in case reachability has already been computed - sp->reachable = s->reachable; + // addstring, addaddr, etc., mark the symbols as reachable. + // In this case that is not necessarily true, so stick to what + // we know before entering this function. + s->reachable = reachable; + sp->reachable = reachable; } vlong diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c index 3edf7253d4..f889aba8a9 100644 --- a/src/cmd/ld/lib.c +++ b/src/cmd/ld/lib.c @@ -222,8 +222,10 @@ loadlib(void) // Since we are simulating the import, we have to provide this string. cgostrsym = "go.string.\"runtime/cgo\""; if(linkrlookup(ctxt, cgostrsym, 0) == nil) { + s = linklookup(ctxt, cgostrsym, 0); + s->type = SRODATA; + s->reachable = 1; addstrdata(cgostrsym, "runtime/cgo"); - linklookup(ctxt, cgostrsym, 0)->type = SRODATA; } } diff --git a/test/linkx.go b/test/linkx.go index 36d16aec9b..06888a229a 100644 --- a/test/linkx.go +++ b/test/linkx.go @@ -1,4 +1,4 @@ -// $G $D/$F.go && $L -X main.tbd hello -X main.overwrite trumped $F.$A && ./$A.out +// $G $D/$F.go && $L -X main.tbd hello -X main.overwrite trumped -X main.nosuchsymbol neverseen $F.$A && ./$A.out // NOTE: This test is not run by 'run.go' and so not run by all.bash. // To run this test you must use the ./run shell script. -- cgit v1.3-5-g9baa