From 930540ca89c63a3b744e652af14f60169401c8df Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 28 Feb 2018 01:19:07 +0000 Subject: libgo: update to final Go 1.10 release Reviewed-on: https://go-review.googlesource.com/97517 From-SVN: r258051 --- libgo/MERGE | 2 +- libgo/VERSION | 2 +- libgo/go/cmd/go/internal/load/pkg.go | 1 + libgo/go/cmd/go/internal/work/exec.go | 15 +++++--- libgo/go/cmd/go/internal/work/security.go | 50 +++++++++++++++++++++++--- libgo/go/cmd/go/internal/work/security_test.go | 7 ++++ 6 files changed, 66 insertions(+), 11 deletions(-) (limited to 'libgo') diff --git a/libgo/MERGE b/libgo/MERGE index 26b8869..b715f06 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -20e228f2fdb44350c858de941dff4aea9f3127b8 +bf86aec25972f3a100c3aa58a6abcbcc35bdea49 The first line of this file holds the git revision number of the last merge done from the master library sources. diff --git a/libgo/VERSION b/libgo/VERSION index dc3cdca..95ec39e 100644 --- a/libgo/VERSION +++ b/libgo/VERSION @@ -1 +1 @@ -go1.10rc2 +go1.10 diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go index ac764b4..52ff6b8 100644 --- a/libgo/go/cmd/go/internal/load/pkg.go +++ b/libgo/go/cmd/go/internal/load/pkg.go @@ -1224,6 +1224,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { // GNU binutils flagfile specifiers, sometimes called "response files"). // To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII. // We accept leading . _ and / as likely in file system paths. +// There is a copy of this function in cmd/compile/internal/gc/noder.go. func SafeArg(name string) bool { if name == "" { return false diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go index 5527e90..40d4602 100644 --- a/libgo/go/cmd/go/internal/work/exec.go +++ b/libgo/go/cmd/go/internal/work/exec.go @@ -945,15 +945,20 @@ func splitPkgConfigOutput(out []byte) []string { // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package. func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, err error) { if pkgs := p.CgoPkgConfig; len(pkgs) > 0 { + var pcflags []string + for len(pkgs) > 0 && strings.HasPrefix(pkgs[0], "--") { + pcflags = append(pcflags, pkgs[0]) + pkgs = pkgs[1:] + } for _, pkg := range pkgs { if !load.SafeArg(pkg) { return nil, nil, fmt.Errorf("invalid pkg-config package name: %s", pkg) } } var out []byte - out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--cflags", "--", pkgs) + out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--cflags", pcflags, "--", pkgs) if err != nil { - b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --cflags "+strings.Join(pkgs, " "), string(out)) + b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --cflags "+strings.Join(pcflags, " ")+strings.Join(pkgs, " "), string(out)) b.Print(err.Error() + "\n") return nil, nil, errPrintedOutput } @@ -963,15 +968,15 @@ func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, return nil, nil, err } } - out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--libs", "--", pkgs) + out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--libs", pcflags, "--", pkgs) if err != nil { - b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pkgs, " "), string(out)) + b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pcflags, " ")+strings.Join(pkgs, " "), string(out)) b.Print(err.Error() + "\n") return nil, nil, errPrintedOutput } if len(out) > 0 { ldflags = strings.Fields(string(out)) - if err := checkLinkerFlags("CFLAGS", "pkg-config --cflags", ldflags); err != nil { + if err := checkLinkerFlags("LDFLAGS", "pkg-config --libs", ldflags); err != nil { return nil, nil, err } } diff --git a/libgo/go/cmd/go/internal/work/security.go b/libgo/go/cmd/go/internal/work/security.go index fee5bee..54fd6b9 100644 --- a/libgo/go/cmd/go/internal/work/security.go +++ b/libgo/go/cmd/go/internal/work/security.go @@ -34,6 +34,7 @@ import ( "fmt" "os" "regexp" + "strings" ) var re = regexp.MustCompile @@ -45,26 +46,42 @@ var validCompilerFlags = []*regexp.Regexp{ re(`-O([^@\-].*)`), re(`-W`), re(`-W([^@,]+)`), // -Wall but not -Wa,-foo. + re(`-f(no-)?blocks`), + re(`-f(no-)?common`), + re(`-f(no-)?constant-cfstrings`), + re(`-f(no-)?exceptions`), + re(`-finput-charset=([^@\-].*)`), + re(`-f(no-)?lto`), + re(`-f(no-)?modules`), re(`-f(no-)?objc-arc`), re(`-f(no-)?omit-frame-pointer`), + re(`-f(no-)?openmp(-simd)?`), + re(`-f(no-)?permissive`), re(`-f(no-)?(pic|PIC|pie|PIE)`), + re(`-f(no-)?rtti`), re(`-f(no-)?split-stack`), re(`-f(no-)?stack-(.+)`), re(`-f(no-)?strict-aliasing`), re(`-fsanitize=(.+)`), re(`-g([^@\-].*)?`), re(`-m(arch|cpu|fpu|tune)=([^@\-].*)`), + re(`-m(no-)?avx[0-9a-z.]*`), + re(`-m(no-)?ms-bitfields`), re(`-m(no-)?stack-(.+)`), re(`-mmacosx-(.+)`), re(`-mnop-fun-dllimport`), + re(`-m(no-)?sse[0-9.]*`), + re(`-pedantic(-errors)?`), + re(`-pipe`), re(`-pthread`), - re(`-std=([^@\-].*)`), + re(`-?-std=([^@\-].*)`), re(`-x([^@\-].*)`), } var validCompilerFlagsWithNextArg = []string{ "-D", "-I", + "-isystem", "-framework", "-x", } @@ -79,16 +96,29 @@ var validLinkerFlags = []*regexp.Regexp{ re(`-m(arch|cpu|fpu|tune)=([^@\-].*)`), re(`-(pic|PIC|pie|PIE)`), re(`-pthread`), + re(`-?-static([-a-z0-9+]*)`), // Note that any wildcards in -Wl need to exclude comma, // since -Wl splits its argument at commas and passes // them all to the linker uninterpreted. Allowing comma // in a wildcard would allow tunnelling arbitrary additional // linker arguments through one of these. + re(`-Wl,--(no-)?as-needed`), + re(`-Wl,-Bdynamic`), + re(`-Wl,-Bstatic`), + re(`-Wl,--disable-new-dtags`), + re(`-Wl,--enable-new-dtags`), + re(`-Wl,--end-group`), + re(`-Wl,-framework,[^,@\-][^,]+`), + re(`-Wl,-headerpad_max_install_names`), + re(`-Wl,--no-undefined`), re(`-Wl,-rpath,([^,@\-][^,]+)`), + re(`-Wl,-search_paths_first`), + re(`-Wl,--start-group`), + re(`-Wl,-?-unresolved-symbols=[^,]+`), re(`-Wl,--(no-)?warn-([^,]+)`), - re(`[a-zA-Z0-9_].*\.(o|obj|dll|dylib|so)`), // direct linker inputs: x.o or libfoo.so (but not -foo.o or @foo.o) + re(`[a-zA-Z0-9_/].*\.(a|o|obj|dll|dylib|so)`), // direct linker inputs: x.o or libfoo.so (but not -foo.o or @foo.o) } var validLinkerFlagsWithNextArg = []string{ @@ -96,6 +126,7 @@ var validLinkerFlagsWithNextArg = []string{ "-l", "-L", "-framework", + "-Wl,-framework", } func checkCompilerFlags(name, source string, list []string) error { @@ -147,10 +178,21 @@ Args: i++ continue Args } + + // Permit -Wl,-framework -Wl,name. + if i+1 < len(list) && + strings.HasPrefix(arg, "-Wl,") && + strings.HasPrefix(list[i+1], "-Wl,") && + load.SafeArg(list[i+1][4:]) && + !strings.Contains(list[i+1][4:], ",") { + i++ + continue Args + } + if i+1 < len(list) { - return fmt.Errorf("invalid flag in %s: %s %s", source, arg, list[i+1]) + return fmt.Errorf("invalid flag in %s: %s %s (see https://golang.org/s/invalidflag)", source, arg, list[i+1]) } - return fmt.Errorf("invalid flag in %s: %s without argument", source, arg) + return fmt.Errorf("invalid flag in %s: %s without argument (see https://golang.org/s/invalidflag)", source, arg) } } Bad: diff --git a/libgo/go/cmd/go/internal/work/security_test.go b/libgo/go/cmd/go/internal/work/security_test.go index 739ab5a..976501b 100644 --- a/libgo/go/cmd/go/internal/work/security_test.go +++ b/libgo/go/cmd/go/internal/work/security_test.go @@ -132,6 +132,9 @@ var goodLinkerFlags = [][]string{ {"-l", "世界"}, {"-L", "framework"}, {"-framework", "Chocolate"}, + {"-Wl,-framework", "-Wl,Chocolate"}, + {"-Wl,-framework,Chocolate"}, + {"-Wl,-unresolved-symbols=ignore-all"}, } var badLinkerFlags = [][]string{ @@ -185,6 +188,10 @@ var badLinkerFlags = [][]string{ {"-l", "-foo"}, {"-framework", "-Caffeine"}, {"-framework", "@Home"}, + {"-Wl,-framework,-Caffeine"}, + {"-Wl,-framework", "-Wl,@Home"}, + {"-Wl,-framework", "@Home"}, + {"-Wl,-framework,Chocolate,@Home"}, {"-x", "--c"}, {"-x", "@obj"}, {"-Wl,-rpath,@foo"}, -- cgit v1.1 From 8cda97ab52eae061d34167a1f786b43a21e7521b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 28 Feb 2018 01:39:03 +0000 Subject: runtime: update AIX memory allocation for new versions Reviewed-on: https://go-review.googlesource.com/97357 From-SVN: r258052 --- libgo/go/runtime/malloc.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'libgo') diff --git a/libgo/go/runtime/malloc.go b/libgo/go/runtime/malloc.go index c27aa48..1405a54 100644 --- a/libgo/go/runtime/malloc.go +++ b/libgo/go/runtime/malloc.go @@ -296,8 +296,8 @@ func mallocinit() { // allocation at 0x40 << 32 because when using 4k pages with 3-level // translation buffers, the user address space is limited to 39 bits // On darwin/arm64, the address space is even smaller. - // On AIX, mmap adresses range start at 0x07000000_00000000 for 64 bits - // processes. + // On AIX, mmap adresses range starts at 0x0700000000000000 for 64-bit + // processes. The new address space allocator starts at 0x0A00000000000000. arenaSize := round(_MaxMem, _PageSize) pSize = bitmapSize + spansSize + arenaSize + _PageSize for i := 0; i <= 0x7f; i++ { @@ -307,13 +307,16 @@ func mallocinit() { case GOARCH == "arm64": p = uintptr(i)<<40 | uintptrMask&(0x0040<<32) case GOOS == "aix": - i = 1 - p = uintptr(i)<<32 | uintptrMask&(0x70<<52) + if i == 0 { + p = uintptrMask&(1<<32) | uintptrMask&(0xa0<<52) + } else { + p = uintptr(i)<<32 | uintptrMask&(0x70<<52) + } default: p = uintptr(i)<<40 | uintptrMask&(0x00c0<<32) } p = uintptr(sysReserve(unsafe.Pointer(p), pSize, &reserved)) - if p != 0 || GOOS == "aix" { // Useless to loop on AIX, as i is forced to 1 + if p != 0 { break } } -- cgit v1.1 From 14710257c19ff60d7c111d41a94f3c3f48ba8d84 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 5 Mar 2018 18:44:44 +0000 Subject: libgo: fix typo in mksysinfo.sh script Fix a small typo in the mksysinfo.sh script (incorrect input file for a grep command). Reviewed-on: https://go-review.googlesource.com/98635 From-SVN: r258259 --- libgo/mksysinfo.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libgo') diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh index 6f7cba7..1b40dbe 100755 --- a/libgo/mksysinfo.sh +++ b/libgo/mksysinfo.sh @@ -1142,7 +1142,7 @@ grep '^const _RLIM_' gen-sysinfo.go | sed -e 's/^\(const \)_\(RLIM_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} if test "${rlimit}" = "_rlimit64" && grep '^const _RLIM64_INFINITY ' gen-sysinfo.go > /dev/null 2>&1; then echo 'const RLIM_INFINITY = _RLIM64_INFINITY' >> ${OUT} -elif grep '^const _RLIM_INFINITY ' gen-sysinfo-go; then +elif grep '^const _RLIM_INFINITY ' gen-sysinfo.go > /dev/null 2>&1; then echo 'const RLIM_INFINITY = _RLIM_INFINITY' >> ${OUT} fi -- cgit v1.1 From 2dab5d909f20be950c35ab4767ba1e0b64cb6bbc Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 7 Mar 2018 14:31:03 +0000 Subject: runtime: use a fence instruction before rdtsc This implements the same choices made in the gc runtime, except that for 32-bit x86 we only use the fence instruction if the processor supports SSE2. The code here is hacked up for speed; the gc runtime uses straight assembler. Reviewed-on: https://go-review.googlesource.com/97715 From-SVN: r258336 --- libgo/runtime/runtime_c.c | 59 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 4 deletions(-) (limited to 'libgo') diff --git a/libgo/runtime/runtime_c.c b/libgo/runtime/runtime_c.c index 88f1adf..c65a7e0 100644 --- a/libgo/runtime/runtime_c.c +++ b/libgo/runtime/runtime_c.c @@ -33,13 +33,47 @@ runtime_atoi(const byte *p, intgo len) return n; } +#if defined(__i386__) || defined(__x86_64__) || defined (__s390__) || defined (__s390x__) + +// When cputicks is just asm instructions, skip the split stack +// prologue for speed. + +int64 runtime_cputicks(void) __attribute__((no_split_stack)); + +#endif + +// Whether the processor supports SSE2. +#if defined (__i386__) +static _Bool hasSSE2; + +// Force appropriate CPU level so that we can call the lfence/mfence +// builtins. + +#pragma GCC push_options +#pragma GCC target("sse2") + +#elif defined(__x86_64__) +#define hasSSE2 true +#endif + +#if defined(__i386__) || defined(__x86_64__) +// Whether to use lfence, as opposed to mfence. +// Set based on cpuid. +static _Bool lfenceBeforeRdtsc; +#endif // defined(__i386__) || defined(__x86_64__) + int64 runtime_cputicks(void) { -#if defined(__386__) || defined(__x86_64__) - uint32 low, high; - asm("rdtsc" : "=a" (low), "=d" (high)); - return (int64)(((uint64)high << 32) | (uint64)low); +#if defined(__i386__) || defined(__x86_64__) + if (hasSSE2) { + if (lfenceBeforeRdtsc) { + __builtin_ia32_lfence(); + } else { + __builtin_ia32_mfence(); + } + } + return __builtin_ia32_rdtsc(); #elif defined (__s390__) || defined (__s390x__) uint64 clock = 0; /* stckf may not write the return variable in case of a clock error, so make @@ -56,6 +90,10 @@ runtime_cputicks(void) #endif } +#if defined(__i386__) +#pragma GCC pop_options +#endif + void runtime_signalstack(byte *p, uintptr n) { @@ -146,8 +184,21 @@ runtime_cpuinit() #if defined(__i386__) || defined(__x86_64__) unsigned int eax, ebx, ecx, edx; + if (__get_cpuid(0, &eax, &ebx, &ecx, &edx)) { + if (eax != 0 + && ebx == 0x756E6547 // "Genu" + && edx == 0x49656E69 // "ineI" + && ecx == 0x6C65746E) { // "ntel" + lfenceBeforeRdtsc = true; + } + } if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { setCpuidECX(ecx); +#if defined(__i386__) + if ((edx & bit_SSE2) != 0) { + hasSSE2 = true; + } +#endif } #if defined(HAVE_AS_X86_AES) -- cgit v1.1 From 123ba0918c9ba27eeba43c885854a553e2b8b6f7 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 7 Mar 2018 15:22:46 +0000 Subject: runtime: push arena on AIX higher due to clashes Reviewed-on: https://go-review.googlesource.com/99117 From-SVN: r258337 --- libgo/go/runtime/malloc.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libgo') diff --git a/libgo/go/runtime/malloc.go b/libgo/go/runtime/malloc.go index 1405a54..c8d5284 100644 --- a/libgo/go/runtime/malloc.go +++ b/libgo/go/runtime/malloc.go @@ -308,9 +308,9 @@ func mallocinit() { p = uintptr(i)<<40 | uintptrMask&(0x0040<<32) case GOOS == "aix": if i == 0 { - p = uintptrMask&(1<<32) | uintptrMask&(0xa0<<52) + p = uintptrMask&(1<<42) | uintptrMask&(0xa0<<52) } else { - p = uintptr(i)<<32 | uintptrMask&(0x70<<52) + p = uintptr(i)<<42 | uintptrMask&(0x70<<52) } default: p = uintptr(i)<<40 | uintptrMask&(0x00c0<<32) -- cgit v1.1 From 300e61fa150ce9fa7bc86784aaa6baeffd174c2f Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 9 Mar 2018 18:21:42 +0000 Subject: commit ce28919112dbb234366816ab39ce060ad45e8ca9 Makefile: add internal/trace to noinst_DATA The internal/trace package is only imported by tests (specifically the tests in runtime/trace) so it must be in noinst_DATA to ensure that it is built before running the tests. This was mostly working because internal/trace has tests itself, and is listed in check-packages.txt before runtime/trace, so typical invocations of make would build internal/trace for checking purposes before checking runtime/trace. But we need this change to make that reliable. Reviewed-on: https://go-review.googlesource.com/99836 From-SVN: r258392 --- libgo/Makefile.am | 1 + libgo/Makefile.in | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'libgo') diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 531f8f0..8f7acfe 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -397,6 +397,7 @@ noinst_DATA = \ golang_org/x/net/internal/nettest.gox \ golang_org/x/net/nettest.gox \ internal/testenv.gox \ + internal/trace.gox \ net/internal/socktest.gox \ os/signal/internal/pty.gox diff --git a/libgo/Makefile.in b/libgo/Makefile.in index fbca83e..70269c7 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -757,8 +757,8 @@ toolexeclibgounicode_DATA = \ # Force them to be built. noinst_DATA = golang_org/x/net/internal/nettest.gox \ golang_org/x/net/nettest.gox internal/testenv.gox \ - net/internal/socktest.gox os/signal/internal/pty.gox \ - zstdpkglist.go zdefaultcc.go + internal/trace.gox net/internal/socktest.gox \ + os/signal/internal/pty.gox zstdpkglist.go zdefaultcc.go @LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file = @LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c @LIBGO_IS_AIX_FALSE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_getncpu_file = runtime/getncpu-none.c -- cgit v1.1 From 8bb2726d08ae3dd89c7085a7972b5a144ccea270 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 15 Mar 2018 16:56:24 +0000 Subject: cmd/go: force LANG=C when looking for compiler version Tested by installing the gcc-locales package and running LANG=de_DE.utf8 go build hello.go Without this change, that fails, as described at https://gcc.gnu.org/PR84765. Reviewed-on: https://go-review.googlesource.com/100737 From-SVN: r258565 --- libgo/go/cmd/go/internal/work/buildid.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'libgo') diff --git a/libgo/go/cmd/go/internal/work/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go index e2ae850..a08de26 100644 --- a/libgo/go/cmd/go/internal/work/buildid.go +++ b/libgo/go/cmd/go/internal/work/buildid.go @@ -234,7 +234,18 @@ func (b *Builder) gccgoToolID(name, language string) (string, error) { // compile an empty file on standard input. cmdline := str.StringList(cfg.BuildToolexec, name, "-###", "-x", language, "-c", "-") cmd := exec.Command(cmdline[0], cmdline[1:]...) - cmd.Env = base.EnvForDir(cmd.Dir, os.Environ()) + + // Strip any LANG or LC_ environment variables, and force + // LANG=C, so that we get the untranslated output. + var env []string + for _, e := range os.Environ() { + if !strings.HasPrefix(e, "LANG=") && !strings.HasPrefix(e, "LC_") { + env = append(env, e) + } + } + env = append(env, "LANG=C") + + cmd.Env = base.EnvForDir(cmd.Dir, env) out, err := cmd.CombinedOutput() if err != nil { return "", fmt.Errorf("%s: %v; output: %q", name, err, out) -- cgit v1.1 From 534d990b353fad0828841d1aa8630ccd0302cb21 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 16 Mar 2018 19:01:40 +0000 Subject: libgo: add runtime/pprof/internal/profile.gox to noinst_DATA Also add noinst_DATA to CHECK_DEPS; it's not needed in practice since `make` will build noinst_DATA, but it's logically required and will make a difference if any of the noinst_DATA sources change between `make` and `make check`. Tony Reix figured out why omitting packages from noinst_DATA didn't seem to matter: because if gccgo can't find foo.gox, it will fall back to reading the export data in foo.o, and foo.o will exist because these packages go into libgo.a. Reviewed-on: https://go-review.googlesource.com/101077 From-SVN: r258606 --- libgo/Makefile.am | 4 +++- libgo/Makefile.in | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'libgo') diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 8f7acfe..7558aab 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -399,7 +399,8 @@ noinst_DATA = \ internal/testenv.gox \ internal/trace.gox \ net/internal/socktest.gox \ - os/signal/internal/pty.gox + os/signal/internal/pty.gox \ + runtime/pprof/internal/profile.gox if LIBGO_IS_RTEMS rtems_task_variable_add_file = runtime/rtems-task-variable-add.c @@ -1094,6 +1095,7 @@ CHECK_DEPS = \ $(toolexeclibgotext_DATA) \ $(toolexeclibgotexttemplate_DATA) \ $(toolexeclibgounicode_DATA) \ + $(noinst_DATA) \ $(noinst_LIBRARIES) if GOC_IS_LLGO diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 70269c7..80c0b89 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -758,7 +758,8 @@ toolexeclibgounicode_DATA = \ noinst_DATA = golang_org/x/net/internal/nettest.gox \ golang_org/x/net/nettest.gox internal/testenv.gox \ internal/trace.gox net/internal/socktest.gox \ - os/signal/internal/pty.gox zstdpkglist.go zdefaultcc.go + os/signal/internal/pty.gox runtime/pprof/internal/profile.gox \ + zstdpkglist.go zdefaultcc.go @LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file = @LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c @LIBGO_IS_AIX_FALSE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_getncpu_file = runtime/getncpu-none.c @@ -1170,7 +1171,8 @@ CHECK_DEPS = $(toolexeclibgo_DATA) $(toolexeclibgoarchive_DATA) \ $(toolexeclibgoruntime_DATA) $(toolexeclibgosync_DATA) \ $(toolexeclibgotesting_DATA) $(toolexeclibgotext_DATA) \ $(toolexeclibgotexttemplate_DATA) $(toolexeclibgounicode_DATA) \ - $(noinst_LIBRARIES) $(am__append_3) $(am__append_4) + $(noinst_DATA) $(noinst_LIBRARIES) $(am__append_3) \ + $(am__append_4) # Pass -ffp-contract=off, or 386-specific options, when building the # math package. MATH_FLAG is defined in configure.ac. -- cgit v1.1 From a8ebf991f368de92ec22a431920cc7c4332be5d4 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 26 Mar 2018 19:29:27 +0000 Subject: runtime: don't check for stale runtime The gccgo runtime is never stale, and on a system with gc sources in ~/go the test may wind up checking whether the gc runtime is stale. Reviewed-on: https://go-review.googlesource.com/102282 From-SVN: r258865 --- libgo/go/runtime/crash_test.go | 3 +++ 1 file changed, 3 insertions(+) (limited to 'libgo') diff --git a/libgo/go/runtime/crash_test.go b/libgo/go/runtime/crash_test.go index 7a099be..602630d 100644 --- a/libgo/go/runtime/crash_test.go +++ b/libgo/go/runtime/crash_test.go @@ -150,6 +150,9 @@ var ( func checkStaleRuntime(t *testing.T) { staleRuntimeOnce.Do(func() { + if runtime.Compiler == "gccgo" { + return + } // 'go run' uses the installed copy of runtime.a, which may be out of date. out, err := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), "list", "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "-f", "{{.Stale}}", "runtime")).CombinedOutput() if err != nil { -- cgit v1.1 From aa4ec2cdff98cdeec085fa14af4267a51e4e1052 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 17 Apr 2018 20:10:49 +0000 Subject: gccgo: suppress "ar rcD" and "-zdefs" on AIX Reviewed-on: https://go-review.googlesource.com/100955 From-SVN: r259445 --- libgo/go/cmd/go/internal/work/gccgo.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'libgo') diff --git a/libgo/go/cmd/go/internal/work/gccgo.go b/libgo/go/cmd/go/internal/work/gccgo.go index 72d4d9d..1ab7e4e 100644 --- a/libgo/go/cmd/go/internal/work/gccgo.go +++ b/libgo/go/cmd/go/internal/work/gccgo.go @@ -190,15 +190,15 @@ func (gccgoToolchain) pack(b *Builder, a *Action, afile string, ofiles []string) } absAfile := mkAbs(objdir, afile) // Try with D modifier first, then without if that fails. - if b.run(a, p.Dir, p.ImportPath, nil, "ar", "rcD", absAfile, absOfiles) != nil { + if cfg.Goos == "aix" || b.run(a, p.Dir, p.ImportPath, nil, "ar", "rcD", absAfile, absOfiles) != nil { + var arArgs []string if cfg.Goos == "aix" && cfg.Goarch == "ppc64" { // AIX puts both 32-bit and 64-bit objects in the same archive. // Tell the AIX "ar" command to only care about 64-bit objects. // AIX "ar" command does not know D option. - return b.run(a, p.Dir, p.ImportPath, nil, "ar", "-X64", "rc", absAfile, absOfiles) - } else { - return b.run(a, p.Dir, p.ImportPath, nil, "ar", "rc", absAfile, absOfiles) + arArgs = append(arArgs, "-X64") } + return b.run(a, p.Dir, p.ImportPath, nil, "ar", "rc", arArgs, absAfile, absOfiles) } return nil } @@ -466,7 +466,10 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string ldflags = append(ldflags, goLibBegin...) ldflags = append(ldflags, "-lgo", "-lgcc_s", "-lgcc", "-lc", "-lgcc") case "shared": - ldflags = append(ldflags, "-zdefs", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc") + if cfg.Goos != "aix" { + ldflags = append(ldflags, "-zdefs") + } + ldflags = append(ldflags, "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc") case "pie": ldflags = append(ldflags, "-pie") -- cgit v1.1 From 4ba010501965cca2091ac1e702105c623ea115b5 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 17 Apr 2018 23:55:17 +0000 Subject: os/signal: disable loading of history during test Bring in https://golang.org/cl/98616 from gc tip. Original CL description: This change modifies Go to disable loading of users' shell history for TestTerminalSignal tests. TestTerminalSignal, as part of its workload, will execute a new interactive bash shell. Bash will attempt to load the user's history from the file pointed to by the HISTFILE environment variable. For users with large histories that may take up to several seconds, pushing the whole test past the 5 second timeout and causing it to fail. Reviewed-on: https://go-review.googlesource.com/107624 From-SVN: r259452 --- libgo/go/os/signal/signal_cgo_test.go | 2 ++ 1 file changed, 2 insertions(+) (limited to 'libgo') diff --git a/libgo/go/os/signal/signal_cgo_test.go b/libgo/go/os/signal/signal_cgo_test.go index 84a2a08..16aeea8 100644 --- a/libgo/go/os/signal/signal_cgo_test.go +++ b/libgo/go/os/signal/signal_cgo_test.go @@ -89,6 +89,8 @@ func TestTerminalSignal(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() cmd := exec.CommandContext(ctx, bash, "--norc", "--noprofile", "-i") + // Clear HISTFILE so that we don't read or clobber the user's bash history. + cmd.Env = append(os.Environ(), "HISTFILE=") cmd.Stdin = slave cmd.Stdout = slave cmd.Stderr = slave -- cgit v1.1 From 447638d2c4d80ee03650406775c0b8a17d246f55 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 20 Apr 2018 20:40:27 +0000 Subject: gotest: only use [TD] on big-endian PPC64 non-AIX systems Reviewed-on: https://go-review.googlesource.com/108457 From-SVN: r259531 --- libgo/testsuite/gotest | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'libgo') diff --git a/libgo/testsuite/gotest b/libgo/testsuite/gotest index 06848fd..434c26d 100755 --- a/libgo/testsuite/gotest +++ b/libgo/testsuite/gotest @@ -506,9 +506,13 @@ localname() { { text="T" - case "$goarch" in - ppc64*) text="[TD]" ;; - esac + + # On systems using PPC64 ELF ABI v1 function symbols show up + # as descriptors in the data section. We assume that $goarch + # distinguishes v1 (ppc64) from v2 (ppc64le). + if test "$goos" != "aix" && test "$goarch" = "ppc64"; then + text="[TD]" + fi symtogo='sed -e s/_test\([^A-Za-z0-9]\)/XXXtest\1/ -e s/.*_\([^_]*\.\)/\1/ -e s/XXXtest/_test/' -- cgit v1.1 From 2885a4939a7c96441210d6b3507524b6970d1013 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 27 Apr 2018 18:01:00 +0000 Subject: re PR go/85429 (Several gotools tests FAIL with Solaris as) PR go/85429 cmd/go: add Solaris assembler syntax for gccgo buildid file The Solaris assembler uses a different syntax for section directives. This is https://golang.org/cl/109140 ported over to gccgo. Reviewed-on: https://go-review.googlesource.com/109141 From-SVN: r259719 --- libgo/go/cmd/go/internal/work/buildid.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'libgo') diff --git a/libgo/go/cmd/go/internal/work/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go index a08de26..7f1ee50 100644 --- a/libgo/go/cmd/go/internal/work/buildid.go +++ b/libgo/go/cmd/go/internal/work/buildid.go @@ -309,7 +309,11 @@ func (b *Builder) gccgoBuildIDELFFile(a *Action) (string, error) { sfile := a.Objdir + "_buildid.s" var buf bytes.Buffer - fmt.Fprintf(&buf, "\t"+`.section .go.buildid,"e"`+"\n") + if cfg.Goos != "solaris" { + fmt.Fprintf(&buf, "\t"+`.section .go.buildid,"e"`+"\n") + } else { + fmt.Fprintf(&buf, "\t"+`.section ".go.buildid",#exclude`+"\n") + } fmt.Fprintf(&buf, "\t.byte ") for i := 0; i < len(a.buildID); i++ { if i > 0 { @@ -322,8 +326,10 @@ func (b *Builder) gccgoBuildIDELFFile(a *Action) (string, error) { fmt.Fprintf(&buf, "%#02x", a.buildID[i]) } fmt.Fprintf(&buf, "\n") - fmt.Fprintf(&buf, "\t"+`.section .note.GNU-stack,"",@progbits`+"\n") - fmt.Fprintf(&buf, "\t"+`.section .note.GNU-split-stack,"",@progbits`+"\n") + if cfg.Goos != "solaris" { + fmt.Fprintf(&buf, "\t"+`.section .note.GNU-stack,"",@progbits`+"\n") + fmt.Fprintf(&buf, "\t"+`.section .note.GNU-split-stack,"",@progbits`+"\n") + } if cfg.BuildN || cfg.BuildX { for _, line := range bytes.Split(buf.Bytes(), []byte("\n")) { -- cgit v1.1 From 8c2e1d6ca5497c08ec72abe9da93e4a7869e0f0e Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 1 May 2018 14:08:44 +0000 Subject: re PR go/85429 (Several gotools tests FAIL with Solaris as) PR go/85429 cmd/go: support more Solaris assembler syntaxes Patch by Rainer Orth. Reviewed-on: https://go-review.googlesource.com/110563 From-SVN: r259797 --- libgo/go/cmd/go/internal/work/buildid.go | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'libgo') diff --git a/libgo/go/cmd/go/internal/work/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go index 7f1ee50..2636128 100644 --- a/libgo/go/cmd/go/internal/work/buildid.go +++ b/libgo/go/cmd/go/internal/work/buildid.go @@ -303,16 +303,35 @@ func (b *Builder) gccgoToolID(name, language string) (string, error) { return id, nil } +// Check if assembler used by gccgo is GNU as. +func assemblerIsGas() bool { + cmd := exec.Command(BuildToolchain.compiler(), "-print-prog-name=as") + assembler, err := cmd.Output() + if err == nil { + cmd := exec.Command(strings.TrimSpace(string(assembler)), "--version") + out, err := cmd.Output() + if err == nil && strings.Contains(string(out), "GNU") { + return true + } else { + return false + } + } else { + return false + } +} + // gccgoBuildIDELFFile creates an assembler file that records the // action's build ID in an SHF_EXCLUDE section. func (b *Builder) gccgoBuildIDELFFile(a *Action) (string, error) { sfile := a.Objdir + "_buildid.s" var buf bytes.Buffer - if cfg.Goos != "solaris" { + if cfg.Goos != "solaris" || assemblerIsGas() { fmt.Fprintf(&buf, "\t"+`.section .go.buildid,"e"`+"\n") - } else { + } else if cfg.Goarch == "sparc" || cfg.Goarch == "sparc64" { fmt.Fprintf(&buf, "\t"+`.section ".go.buildid",#exclude`+"\n") + } else { // cfg.Goarch == "386" || cfg.Goarch == "amd64" + fmt.Fprintf(&buf, "\t"+`.section .go.buildid,#exclude`+"\n") } fmt.Fprintf(&buf, "\t.byte ") for i := 0; i < len(a.buildID); i++ { -- cgit v1.1 From 019808c95c540a830a64c132257bde018abf6a1e Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 2 May 2018 21:53:30 +0000 Subject: libgo: break dependence on libgcc unwind-pe.h The C portion of the Go runtime includes the header "unwind-pe.h" from libgcc, which contains some constants and a few small routines for decoding pointer values within unwind info. This patch gets rid of that include and instead adds a re-implementation of that functionality in the single file that uses it. The intent is to allow the C runtime portion of libgo to be built without a companion GCC installation. Reviewed-on: https://go-review.googlesource.com/90235 From-SVN: r259861 --- libgo/runtime/go-unwind.c | 167 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 165 insertions(+), 2 deletions(-) (limited to 'libgo') diff --git a/libgo/runtime/go-unwind.c b/libgo/runtime/go-unwind.c index 4c9fb49..536a619 100644 --- a/libgo/runtime/go-unwind.c +++ b/libgo/runtime/go-unwind.c @@ -10,11 +10,30 @@ #include #include "unwind.h" -#define NO_SIZE_OF_ENCODED_VALUE -#include "unwind-pe.h" #include "runtime.h" +/* These constants are documented here: + https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/dwarfext.html + */ + +#define DW_EH_PE_omit 0xff +#define DW_EH_PE_absptr 0x00 +#define DW_EH_PE_uleb128 0x01 +#define DW_EH_PE_udata2 0x02 +#define DW_EH_PE_udata4 0x03 +#define DW_EH_PE_udata8 0x04 +#define DW_EH_PE_sleb128 0x09 +#define DW_EH_PE_sdata2 0x0A +#define DW_EH_PE_sdata4 0x0B +#define DW_EH_PE_sdata8 0x0C +#define DW_EH_PE_pcrel 0x10 +#define DW_EH_PE_textrel 0x20 +#define DW_EH_PE_datarel 0x30 +#define DW_EH_PE_funcrel 0x40 +#define DW_EH_PE_aligned 0x50 +#define DW_EH_PE_indirect 0x80 + /* The code for a Go exception. */ #ifdef __ARM_EABI_UNWINDER__ @@ -109,6 +128,150 @@ throwException () abort (); } +static inline _Unwind_Ptr +encoded_value_base (uint8_t encoding, struct _Unwind_Context *context) +{ + if (encoding == DW_EH_PE_omit) + return 0; + switch (encoding & 0x70) + { + case DW_EH_PE_absptr: + case DW_EH_PE_pcrel: + case DW_EH_PE_aligned: + return 0; + case DW_EH_PE_textrel: + return _Unwind_GetTextRelBase(context); + case DW_EH_PE_datarel: + return _Unwind_GetDataRelBase(context); + case DW_EH_PE_funcrel: + return _Unwind_GetRegionStart(context); + } + abort (); +} + +/* Read an unsigned leb128 value. */ + +static inline const uint8_t * +read_uleb128 (const uint8_t *p, _uleb128_t *val) +{ + unsigned int shift = 0; + _uleb128_t result = 0; + uint8_t byte; + + do + { + byte = *p++; + result |= ((_uleb128_t)byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + *val = result; + return p; +} + +/* Similar, but read a signed leb128 value. */ + +static inline const uint8_t * +read_sleb128 (const uint8_t *p, _sleb128_t *val) +{ + unsigned int shift = 0; + _uleb128_t result = 0; + uint8_t byte; + + do + { + byte = *p++; + result |= ((_uleb128_t)byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + /* sign extension */ + if (shift < (8 * sizeof(result)) && (byte & 0x40) != 0) + result |= (((_uleb128_t)~0) << shift); + + *val = (_sleb128_t)result; + return p; +} + +#define ROUND_UP_TO_PVB(x) (x + sizeof(void *) - 1) &- sizeof(void *) + +#define COPY_AND_ADVANCE(dst, ptr, typ) \ + (dst = *((const typ*)ptr), \ + ptr += sizeof(typ)) + +static inline const uint8_t * +read_encoded_value (struct _Unwind_Context *context, uint8_t encoding, + const uint8_t *p, _Unwind_Ptr *val) +{ + _Unwind_Ptr base = encoded_value_base (encoding, context); + _Unwind_Internal_Ptr decoded = 0; + const uint8_t *origp = p; + + if (encoding == DW_EH_PE_aligned) + { + _Unwind_Internal_Ptr uip = (_Unwind_Internal_Ptr)p; + uip = ROUND_UP_TO_PVB (uip); + decoded = *(_Unwind_Internal_Ptr *)uip; + p = (const uint8_t *)(uip + sizeof(void *)); + } + else + { + switch (encoding & 0x0f) + { + case DW_EH_PE_sdata2: + case DW_EH_PE_udata2: + COPY_AND_ADVANCE (decoded, p, uint16_t); + break; + case DW_EH_PE_sdata4: + case DW_EH_PE_udata4: + COPY_AND_ADVANCE (decoded, p, uint32_t); + break; + case DW_EH_PE_sdata8: + case DW_EH_PE_udata8: + COPY_AND_ADVANCE (decoded, p, uint64_t); + break; + case DW_EH_PE_uleb128: + { + _uleb128_t value; + p = read_uleb128 (p, &value); + decoded = (_Unwind_Internal_Ptr)value; + break; + } + case DW_EH_PE_sleb128: + { + _sleb128_t value; + p = read_sleb128 (p, &value); + decoded = (_Unwind_Internal_Ptr)value; + break; + } + case DW_EH_PE_absptr: + decoded = (_Unwind_Internal_Ptr)(*(const void *const *)p); + p += sizeof(void *); + break; + default: + abort (); + } + + if (decoded == 0) + { + *val = decoded; + return p; + } + + if ((encoding & 0x70) == DW_EH_PE_pcrel) + decoded += ((_Unwind_Internal_Ptr)origp); + else + decoded += base; + + if ((encoding & DW_EH_PE_indirect) != 0) + decoded = *(_Unwind_Internal_Ptr *)decoded; + } + *val = decoded; + return p; +} + /* The rest of this code is really similar to gcc/unwind-c.c and libjava/exception.cc. */ -- cgit v1.1 From cec9701b510ebcb5cfdf431a5b0dd9c143f1da69 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 2 May 2018 21:57:35 +0000 Subject: libgo: refactor code to enumerate stdlib packages Move the list of libgo, gotool, and check-target packages into separate files, then read the file contents as part of the build process on the fly. This is intended to enable other build tooling to share the canonical list of target packages (avoid duplication). Reviewed-on: https://go-review.googlesource.com/89515 libgo: revise rules for runtime.inc generation Refactor code for generating runtime.inc: extract out the relevant commands and place them in a separate shell script ("mkruntimeinc.sh"). Update rules to avoid generating macros whose names begin with "$", such as "#define $sinkconst0 0". Reviewed-on: https://go-review.googlesource.com/85955 From-SVN: r259863 --- libgo/Makefile.am | 402 ++------------------------------------------- libgo/Makefile.in | 404 ++-------------------------------------------- libgo/check-packages.txt | 162 +++++++++++++++++++ libgo/gotool-packages.txt | 30 ++++ libgo/libgo-packages.txt | 177 ++++++++++++++++++++ libgo/mkruntimeinc.sh | 33 ++++ 6 files changed, 424 insertions(+), 784 deletions(-) create mode 100644 libgo/check-packages.txt create mode 100644 libgo/gotool-packages.txt create mode 100644 libgo/libgo-packages.txt create mode 100755 libgo/mkruntimeinc.sh (limited to 'libgo') diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 7558aab..119d241 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -593,25 +593,13 @@ s-zdefaultcc: Makefile $(SHELL) $(srcdir)/../move-if-change zdefaultcc.go.tmp zdefaultcc.go $(STAMP) $@ -# _Complex_lock and _Reader_lock are Go translations of some AIX system -# types and should not be exported back to C -# semt is a Go translation of the C type sem_t; it fails to convert on -# some systems and need not be exported back to C. -# sigset conflicts with system type sigset on AIX, so we need to rename it +# Post-process runtime.inc.raw (raw output of -fgo-c-header option when +# compiling runtime) to prune out certain types that should not be +# exported back to C. See comments in mkruntimeinc.sh for more details. runtime.inc: s-runtime-inc; @true s-runtime-inc: runtime.lo Makefile - rm -f runtime.inc.tmp2 runtime.inc.tmp3 - grep -v "#define _" runtime.inc.tmp | grep -v "#define [cm][01234] " | grep -v "#define empty " > runtime.inc.tmp2 - for pattern in '_[GP][a-z]' _Max _Lock _Sig _Trace _MHeap _Num; do \ - grep "#define $$pattern" runtime.inc.tmp >> runtime.inc.tmp2; \ - done - for TYPE in _Complex_lock _Reader_lock semt; do \ - sed -e '/struct '$${TYPE}' {/,/^}/s/^.*$$//' runtime.inc.tmp2 > runtime.inc.tmp3; \ - mv runtime.inc.tmp3 runtime.inc.tmp2; \ - done - sed -e 's/sigset/sigset_go/' runtime.inc.tmp2 > runtime.inc.tmp3 - $(SHELL) $(srcdir)/mvifdiff.sh runtime.inc.tmp3 runtime.inc - rm -f runtime.inc.tmp2 runtime.inc.tmp3 + $(SHELL) $(srcdir)/mkruntimeinc.sh + $(SHELL) $(srcdir)/mvifdiff.sh tmp-runtime.inc runtime.inc $(STAMP) $@ noinst_DATA += zstdpkglist.go zdefaultcc.go @@ -714,184 +702,7 @@ else syscall_lib_clone_lo = endif -PACKAGES = \ - archive/tar \ - archive/zip \ - bufio \ - bytes \ - compress/bzip2 \ - compress/flate \ - compress/gzip \ - compress/lzw \ - compress/zlib \ - container/heap \ - container/list \ - container/ring \ - context \ - crypto \ - crypto/aes \ - crypto/cipher \ - crypto/des \ - crypto/dsa \ - crypto/ecdsa \ - crypto/elliptic \ - crypto/hmac \ - crypto/internal/cipherhw \ - crypto/md5 \ - crypto/rand \ - crypto/rc4 \ - crypto/rsa \ - crypto/sha1 \ - crypto/sha256 \ - crypto/sha512 \ - crypto/subtle \ - crypto/tls \ - crypto/x509 \ - crypto/x509/pkix \ - database/sql \ - database/sql/driver \ - debug/dwarf \ - debug/elf \ - debug/gosym \ - debug/macho \ - debug/pe \ - debug/plan9obj \ - debug/xcoff \ - encoding \ - encoding/ascii85 \ - encoding/asn1 \ - encoding/base32 \ - encoding/base64 \ - encoding/binary \ - encoding/csv \ - encoding/gob \ - encoding/hex \ - encoding/json \ - encoding/pem \ - encoding/xml \ - errors \ - expvar \ - flag \ - fmt \ - go/ast \ - go/build \ - go/constant \ - go/doc \ - go/format \ - go/importer \ - go/internal/gccgoimporter \ - go/internal/gcimporter \ - go/internal/srcimporter \ - go/parser \ - go/printer \ - go/scanner \ - go/token \ - go/types \ - golang_org/x/crypto/chacha20poly1305 \ - golang_org/x/crypto/chacha20poly1305/internal/chacha20 \ - golang_org/x/crypto/cryptobyte \ - golang_org/x/crypto/cryptobyte/asn1 \ - golang_org/x/crypto/curve25519 \ - golang_org/x/crypto/poly1305 \ - golang_org/x/net/http2/hpack \ - golang_org/x/net/idna \ - golang_org/x/net/internal/nettest \ - golang_org/x/net/lex/httplex \ - golang_org/x/net/nettest \ - golang_org/x/net/proxy \ - golang_org/x/text/secure/bidirule \ - golang_org/x/text/transform \ - golang_org/x/text/unicode/bidi \ - golang_org/x/text/unicode/norm \ - golang_org/x/text/width \ - hash \ - hash/adler32 \ - hash/crc32 \ - hash/crc64 \ - hash/fnv \ - html \ - html/template \ - image \ - image/color \ - image/color/palette \ - image/draw \ - image/gif \ - image/internal/imageutil \ - image/jpeg \ - image/png \ - index/suffixarray \ - internal/nettrace \ - internal/poll \ - internal/race \ - internal/singleflight \ - internal/syscall/unix \ - internal/testenv \ - internal/testlog \ - internal/trace \ - io \ - io/ioutil \ - log \ - log/syslog \ - math \ - math/big \ - math/bits \ - math/cmplx \ - math/rand \ - mime \ - mime/multipart \ - mime/quotedprintable \ - net \ - net/http \ - net/http/cgi \ - net/http/cookiejar \ - net/http/fcgi \ - net/http/httptest \ - net/http/httptrace \ - net/http/httputil \ - net/http/internal \ - net/http/pprof \ - net/internal/socktest \ - net/mail \ - net/rpc \ - net/rpc/jsonrpc \ - net/smtp \ - net/textproto \ - net/url \ - os \ - os/exec \ - os/signal \ - os/signal/internal/pty \ - os/user \ - path \ - path/filepath \ - reflect \ - regexp \ - regexp/syntax \ - runtime \ - runtime/debug \ - runtime/internal/atomic \ - runtime/internal/sys \ - runtime/pprof \ - runtime/pprof/internal/profile \ - runtime/trace \ - sort \ - strconv \ - strings \ - sync \ - sync/atomic \ - syscall \ - testing \ - testing/internal/testdeps \ - testing/iotest \ - testing/quick \ - text/scanner \ - text/tabwriter \ - text/template \ - text/template/parse \ - time \ - unicode \ - unicode/utf16 \ - unicode/utf8 +PACKAGES = $(shell cat $(srcdir)/libgo-packages.txt) libgo_go_objs = \ $(addsuffix .lo,$(PACKAGES)) \ @@ -939,37 +750,7 @@ libgolibbegin_a_SOURCES = \ libgolibbegin_a_CFLAGS = $(AM_CFLAGS) -fPIC -GOTOOL_PACKAGES = \ - cmd/go/internal/base \ - cmd/go/internal/bug \ - cmd/go/internal/cache \ - cmd/go/internal/cfg \ - cmd/go/internal/clean \ - cmd/go/internal/cmdflag \ - cmd/go/internal/doc \ - cmd/go/internal/envcmd \ - cmd/go/internal/fix \ - cmd/go/internal/fmtcmd \ - cmd/go/internal/generate \ - cmd/go/internal/get \ - cmd/go/internal/help \ - cmd/go/internal/list \ - cmd/go/internal/load \ - cmd/go/internal/run \ - cmd/go/internal/str \ - cmd/go/internal/test \ - cmd/go/internal/tool \ - cmd/go/internal/version \ - cmd/go/internal/vet \ - cmd/go/internal/web \ - cmd/go/internal/work \ - cmd/internal/browser \ - cmd/internal/buildid \ - cmd/internal/edit \ - cmd/internal/objabi \ - cmd/internal/test2json \ - cmd/vet/internal/cfg \ - cmd/vet/internal/whitelist +GOTOOL_PACKAGES = $(shell cat $(srcdir)/gotool-packages.txt) libgotool_a_SOURCES = libgotool_a_DEPENDENCIES = $(addsuffix .lo,$(GOTOOL_PACKAGES)) @@ -1156,7 +937,7 @@ extra_go_files_syscall = \ syscall.lo.dep: $(extra_go_files_syscall) # Pass -fgo-compiling-runtime when compiling the runtime package. -runtime_lo_GOCFLAGS = -fgo-c-header=runtime.inc.tmp -fgo-compiling-runtime +runtime_lo_GOCFLAGS = -fgo-c-header=runtime.inc.raw -fgo-compiling-runtime runtime_check_GOCFLAGS = -fgo-compiling-runtime runtime_internal_atomic_lo_GOCFLAGS = -fgo-compiling-runtime runtime_internal_atomic_lo_check_GOCFLAGS = -fgo-compiling-runtime @@ -1281,171 +1062,10 @@ golang_org_x_net_lif_check = \ endif -TEST_PACKAGES = \ - bufio/check \ - bytes/check \ - context/check \ - crypto/check \ - errors/check \ - expvar/check \ - flag/check \ - fmt/check \ - hash/check \ - html/check \ - image/check \ - io/check \ - log/check \ - math/check \ - mime/check \ - net/check \ - os/check \ - path/check \ - reflect/check \ - regexp/check \ - runtime/check \ - sort/check \ - strconv/check \ - strings/check \ - sync/check \ - syscall/check \ - time/check \ - unicode/check \ - archive/tar/check \ - archive/zip/check \ - cmd/go/internal/cache/check \ - cmd/go/internal/generate/check \ - cmd/go/internal/get/check \ - cmd/go/internal/load/check \ - cmd/go/internal/work/check \ - cmd/internal/buildid/check \ - cmd/internal/edit/check \ - cmd/internal/objabi/check \ - cmd/internal/test2json/check \ - cmd/vet/internal/cfg/check \ - compress/bzip2/check \ - compress/flate/check \ - compress/gzip/check \ - compress/lzw/check \ - compress/zlib/check \ - container/heap/check \ - container/list/check \ - container/ring/check \ - crypto/aes/check \ - crypto/cipher/check \ - crypto/des/check \ - crypto/dsa/check \ - crypto/ecdsa/check \ - crypto/elliptic/check \ - crypto/hmac/check \ - crypto/md5/check \ - crypto/rand/check \ - crypto/rc4/check \ - crypto/rsa/check \ - crypto/sha1/check \ - crypto/sha256/check \ - crypto/sha512/check \ - crypto/subtle/check \ - crypto/tls/check \ - crypto/x509/check \ - database/sql/check \ - database/sql/driver/check \ - debug/dwarf/check \ - debug/elf/check \ - debug/macho/check \ - debug/pe/check \ - debug/plan9obj/check \ - debug/xcoff/check \ - encoding/ascii85/check \ - encoding/asn1/check \ - encoding/base32/check \ - encoding/base64/check \ - encoding/binary/check \ - encoding/csv/check \ - encoding/gob/check \ - encoding/hex/check \ - encoding/json/check \ - encoding/pem/check \ - encoding/xml/check \ - html/template/check \ - go/ast/check \ - go/build/check \ - go/constant/check \ - go/doc/check \ - go/format/check \ - go/importer/check \ - go/internal/gcimporter/check \ - go/internal/gccgoimporter/check \ - go/internal/srcimporter/check \ - go/parser/check \ - go/printer/check \ - go/scanner/check \ - go/token/check \ - go/types/check \ - golang_org/x/crypto/chacha20poly1305/check \ - golang_org/x/crypto/chacha20poly1305/internal/chacha20/check \ - golang_org/x/crypto/cryptobyte/check \ - golang_org/x/crypto/curve25519/check \ - golang_org/x/crypto/poly1305/check \ - golang_org/x/net/http2/hpack/check \ - golang_org/x/net/idna/check \ - golang_org/x/net/lex/httplex/check \ +TPACKAGES = $(shell cat $(srcdir)/check-packages.txt) +TEST_PACKAGES = $(addsuffix /check,$(TPACKAGES)) \ $(golang_org_x_net_lif_check) \ - golang_org/x/net/proxy/check \ - $(golang_org_x_net_route_check) \ - hash/adler32/check \ - hash/crc32/check \ - hash/crc64/check \ - hash/fnv/check \ - image/color/check \ - image/draw/check \ - image/jpeg/check \ - image/png/check \ - index/suffixarray/check \ - internal/poll/check \ - internal/singleflight/check \ - internal/trace/check \ - io/ioutil/check \ - log/syslog/check \ - math/big/check \ - math/bits/check \ - math/cmplx/check \ - math/rand/check \ - mime/multipart/check \ - mime/quotedprintable/check \ - net/http/check \ - net/http/cgi/check \ - net/http/cookiejar/check \ - net/http/fcgi/check \ - net/http/httptest/check \ - net/http/httptrace/check \ - net/http/httputil/check \ - net/http/internal/check \ - net/internal/socktest/check \ - net/mail/check \ - net/rpc/check \ - net/smtp/check \ - net/textproto/check \ - net/url/check \ - net/rpc/jsonrpc/check \ - os/exec/check \ - os/signal/check \ - os/user/check \ - path/filepath/check \ - regexp/syntax/check \ - runtime/debug/check \ - runtime/internal/atomic/check \ - runtime/internal/sys/check \ - runtime/pprof/check \ - runtime/pprof/internal/profile/check \ - runtime/trace/check \ - sync/atomic/check \ - text/scanner/check \ - text/tabwriter/check \ - text/template/check \ - text/template/parse/check \ - testing/quick/check \ - unicode/utf16/check \ - unicode/utf8/check + $(golang_org_x_net_route_check) check: check-tail check-recursive: check-head diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 80c0b89..a30e427 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -820,185 +820,7 @@ SYSINFO_FLAGS = \ @LIBGO_IS_LINUX_FALSE@syscall_lib_clone_lo = @LIBGO_IS_LINUX_TRUE@syscall_lib_clone_lo = syscall/clone_linux.lo -PACKAGES = \ - archive/tar \ - archive/zip \ - bufio \ - bytes \ - compress/bzip2 \ - compress/flate \ - compress/gzip \ - compress/lzw \ - compress/zlib \ - container/heap \ - container/list \ - container/ring \ - context \ - crypto \ - crypto/aes \ - crypto/cipher \ - crypto/des \ - crypto/dsa \ - crypto/ecdsa \ - crypto/elliptic \ - crypto/hmac \ - crypto/internal/cipherhw \ - crypto/md5 \ - crypto/rand \ - crypto/rc4 \ - crypto/rsa \ - crypto/sha1 \ - crypto/sha256 \ - crypto/sha512 \ - crypto/subtle \ - crypto/tls \ - crypto/x509 \ - crypto/x509/pkix \ - database/sql \ - database/sql/driver \ - debug/dwarf \ - debug/elf \ - debug/gosym \ - debug/macho \ - debug/pe \ - debug/plan9obj \ - debug/xcoff \ - encoding \ - encoding/ascii85 \ - encoding/asn1 \ - encoding/base32 \ - encoding/base64 \ - encoding/binary \ - encoding/csv \ - encoding/gob \ - encoding/hex \ - encoding/json \ - encoding/pem \ - encoding/xml \ - errors \ - expvar \ - flag \ - fmt \ - go/ast \ - go/build \ - go/constant \ - go/doc \ - go/format \ - go/importer \ - go/internal/gccgoimporter \ - go/internal/gcimporter \ - go/internal/srcimporter \ - go/parser \ - go/printer \ - go/scanner \ - go/token \ - go/types \ - golang_org/x/crypto/chacha20poly1305 \ - golang_org/x/crypto/chacha20poly1305/internal/chacha20 \ - golang_org/x/crypto/cryptobyte \ - golang_org/x/crypto/cryptobyte/asn1 \ - golang_org/x/crypto/curve25519 \ - golang_org/x/crypto/poly1305 \ - golang_org/x/net/http2/hpack \ - golang_org/x/net/idna \ - golang_org/x/net/internal/nettest \ - golang_org/x/net/lex/httplex \ - golang_org/x/net/nettest \ - golang_org/x/net/proxy \ - golang_org/x/text/secure/bidirule \ - golang_org/x/text/transform \ - golang_org/x/text/unicode/bidi \ - golang_org/x/text/unicode/norm \ - golang_org/x/text/width \ - hash \ - hash/adler32 \ - hash/crc32 \ - hash/crc64 \ - hash/fnv \ - html \ - html/template \ - image \ - image/color \ - image/color/palette \ - image/draw \ - image/gif \ - image/internal/imageutil \ - image/jpeg \ - image/png \ - index/suffixarray \ - internal/nettrace \ - internal/poll \ - internal/race \ - internal/singleflight \ - internal/syscall/unix \ - internal/testenv \ - internal/testlog \ - internal/trace \ - io \ - io/ioutil \ - log \ - log/syslog \ - math \ - math/big \ - math/bits \ - math/cmplx \ - math/rand \ - mime \ - mime/multipart \ - mime/quotedprintable \ - net \ - net/http \ - net/http/cgi \ - net/http/cookiejar \ - net/http/fcgi \ - net/http/httptest \ - net/http/httptrace \ - net/http/httputil \ - net/http/internal \ - net/http/pprof \ - net/internal/socktest \ - net/mail \ - net/rpc \ - net/rpc/jsonrpc \ - net/smtp \ - net/textproto \ - net/url \ - os \ - os/exec \ - os/signal \ - os/signal/internal/pty \ - os/user \ - path \ - path/filepath \ - reflect \ - regexp \ - regexp/syntax \ - runtime \ - runtime/debug \ - runtime/internal/atomic \ - runtime/internal/sys \ - runtime/pprof \ - runtime/pprof/internal/profile \ - runtime/trace \ - sort \ - strconv \ - strings \ - sync \ - sync/atomic \ - syscall \ - testing \ - testing/internal/testdeps \ - testing/iotest \ - testing/quick \ - text/scanner \ - text/tabwriter \ - text/template \ - text/template/parse \ - time \ - unicode \ - unicode/utf16 \ - unicode/utf8 - +PACKAGES = $(shell cat $(srcdir)/libgo-packages.txt) libgo_go_objs = \ $(addsuffix .lo,$(PACKAGES)) \ bytes/index.lo \ @@ -1042,38 +864,7 @@ libgolibbegin_a_SOURCES = \ runtime/go-libmain.c libgolibbegin_a_CFLAGS = $(AM_CFLAGS) -fPIC -GOTOOL_PACKAGES = \ - cmd/go/internal/base \ - cmd/go/internal/bug \ - cmd/go/internal/cache \ - cmd/go/internal/cfg \ - cmd/go/internal/clean \ - cmd/go/internal/cmdflag \ - cmd/go/internal/doc \ - cmd/go/internal/envcmd \ - cmd/go/internal/fix \ - cmd/go/internal/fmtcmd \ - cmd/go/internal/generate \ - cmd/go/internal/get \ - cmd/go/internal/help \ - cmd/go/internal/list \ - cmd/go/internal/load \ - cmd/go/internal/run \ - cmd/go/internal/str \ - cmd/go/internal/test \ - cmd/go/internal/tool \ - cmd/go/internal/version \ - cmd/go/internal/vet \ - cmd/go/internal/web \ - cmd/go/internal/work \ - cmd/internal/browser \ - cmd/internal/buildid \ - cmd/internal/edit \ - cmd/internal/objabi \ - cmd/internal/test2json \ - cmd/vet/internal/cfg \ - cmd/vet/internal/whitelist - +GOTOOL_PACKAGES = $(shell cat $(srcdir)/gotool-packages.txt) libgotool_a_SOURCES = libgotool_a_DEPENDENCIES = $(addsuffix .lo,$(GOTOOL_PACKAGES)) libgotool_a_LIBADD = $(addsuffix .o,$(GOTOOL_PACKAGES)) @@ -1191,7 +982,7 @@ extra_go_files_syscall = \ # Pass -fgo-compiling-runtime when compiling the runtime package. -runtime_lo_GOCFLAGS = -fgo-c-header=runtime.inc.tmp -fgo-compiling-runtime +runtime_lo_GOCFLAGS = -fgo-c-header=runtime.inc.raw -fgo-compiling-runtime runtime_check_GOCFLAGS = -fgo-compiling-runtime runtime_internal_atomic_lo_GOCFLAGS = -fgo-compiling-runtime runtime_internal_atomic_lo_check_GOCFLAGS = -fgo-compiling-runtime @@ -1236,171 +1027,10 @@ extra_check_libs_cmd_vet_internal_cfg = $(abs_builddir)/libgotool.a @LIBGO_IS_SOLARIS_TRUE@golang_org_x_net_lif_check = \ @LIBGO_IS_SOLARIS_TRUE@ golang_org/x/net/lif/check -TEST_PACKAGES = \ - bufio/check \ - bytes/check \ - context/check \ - crypto/check \ - errors/check \ - expvar/check \ - flag/check \ - fmt/check \ - hash/check \ - html/check \ - image/check \ - io/check \ - log/check \ - math/check \ - mime/check \ - net/check \ - os/check \ - path/check \ - reflect/check \ - regexp/check \ - runtime/check \ - sort/check \ - strconv/check \ - strings/check \ - sync/check \ - syscall/check \ - time/check \ - unicode/check \ - archive/tar/check \ - archive/zip/check \ - cmd/go/internal/cache/check \ - cmd/go/internal/generate/check \ - cmd/go/internal/get/check \ - cmd/go/internal/load/check \ - cmd/go/internal/work/check \ - cmd/internal/buildid/check \ - cmd/internal/edit/check \ - cmd/internal/objabi/check \ - cmd/internal/test2json/check \ - cmd/vet/internal/cfg/check \ - compress/bzip2/check \ - compress/flate/check \ - compress/gzip/check \ - compress/lzw/check \ - compress/zlib/check \ - container/heap/check \ - container/list/check \ - container/ring/check \ - crypto/aes/check \ - crypto/cipher/check \ - crypto/des/check \ - crypto/dsa/check \ - crypto/ecdsa/check \ - crypto/elliptic/check \ - crypto/hmac/check \ - crypto/md5/check \ - crypto/rand/check \ - crypto/rc4/check \ - crypto/rsa/check \ - crypto/sha1/check \ - crypto/sha256/check \ - crypto/sha512/check \ - crypto/subtle/check \ - crypto/tls/check \ - crypto/x509/check \ - database/sql/check \ - database/sql/driver/check \ - debug/dwarf/check \ - debug/elf/check \ - debug/macho/check \ - debug/pe/check \ - debug/plan9obj/check \ - debug/xcoff/check \ - encoding/ascii85/check \ - encoding/asn1/check \ - encoding/base32/check \ - encoding/base64/check \ - encoding/binary/check \ - encoding/csv/check \ - encoding/gob/check \ - encoding/hex/check \ - encoding/json/check \ - encoding/pem/check \ - encoding/xml/check \ - html/template/check \ - go/ast/check \ - go/build/check \ - go/constant/check \ - go/doc/check \ - go/format/check \ - go/importer/check \ - go/internal/gcimporter/check \ - go/internal/gccgoimporter/check \ - go/internal/srcimporter/check \ - go/parser/check \ - go/printer/check \ - go/scanner/check \ - go/token/check \ - go/types/check \ - golang_org/x/crypto/chacha20poly1305/check \ - golang_org/x/crypto/chacha20poly1305/internal/chacha20/check \ - golang_org/x/crypto/cryptobyte/check \ - golang_org/x/crypto/curve25519/check \ - golang_org/x/crypto/poly1305/check \ - golang_org/x/net/http2/hpack/check \ - golang_org/x/net/idna/check \ - golang_org/x/net/lex/httplex/check \ +TPACKAGES = $(shell cat $(srcdir)/check-packages.txt) +TEST_PACKAGES = $(addsuffix /check,$(TPACKAGES)) \ $(golang_org_x_net_lif_check) \ - golang_org/x/net/proxy/check \ - $(golang_org_x_net_route_check) \ - hash/adler32/check \ - hash/crc32/check \ - hash/crc64/check \ - hash/fnv/check \ - image/color/check \ - image/draw/check \ - image/jpeg/check \ - image/png/check \ - index/suffixarray/check \ - internal/poll/check \ - internal/singleflight/check \ - internal/trace/check \ - io/ioutil/check \ - log/syslog/check \ - math/big/check \ - math/bits/check \ - math/cmplx/check \ - math/rand/check \ - mime/multipart/check \ - mime/quotedprintable/check \ - net/http/check \ - net/http/cgi/check \ - net/http/cookiejar/check \ - net/http/fcgi/check \ - net/http/httptest/check \ - net/http/httptrace/check \ - net/http/httputil/check \ - net/http/internal/check \ - net/internal/socktest/check \ - net/mail/check \ - net/rpc/check \ - net/smtp/check \ - net/textproto/check \ - net/url/check \ - net/rpc/jsonrpc/check \ - os/exec/check \ - os/signal/check \ - os/user/check \ - path/filepath/check \ - regexp/syntax/check \ - runtime/debug/check \ - runtime/internal/atomic/check \ - runtime/internal/sys/check \ - runtime/pprof/check \ - runtime/pprof/internal/profile/check \ - runtime/trace/check \ - sync/atomic/check \ - text/scanner/check \ - text/tabwriter/check \ - text/template/check \ - text/template/parse/check \ - testing/quick/check \ - unicode/utf16/check \ - unicode/utf8/check + $(golang_org_x_net_route_check) MOSTLYCLEANFILES = \ s-runtime_sysinfo s-sigtab s-runtime-inc s-zstdpkglist \ @@ -3173,25 +2803,13 @@ s-zdefaultcc: Makefile $(SHELL) $(srcdir)/../move-if-change zdefaultcc.go.tmp zdefaultcc.go $(STAMP) $@ -# _Complex_lock and _Reader_lock are Go translations of some AIX system -# types and should not be exported back to C -# semt is a Go translation of the C type sem_t; it fails to convert on -# some systems and need not be exported back to C. -# sigset conflicts with system type sigset on AIX, so we need to rename it +# Post-process runtime.inc.raw (raw output of -fgo-c-header option when +# compiling runtime) to prune out certain types that should not be +# exported back to C. See comments in mkruntimeinc.sh for more details. runtime.inc: s-runtime-inc; @true s-runtime-inc: runtime.lo Makefile - rm -f runtime.inc.tmp2 runtime.inc.tmp3 - grep -v "#define _" runtime.inc.tmp | grep -v "#define [cm][01234] " | grep -v "#define empty " > runtime.inc.tmp2 - for pattern in '_[GP][a-z]' _Max _Lock _Sig _Trace _MHeap _Num; do \ - grep "#define $$pattern" runtime.inc.tmp >> runtime.inc.tmp2; \ - done - for TYPE in _Complex_lock _Reader_lock semt; do \ - sed -e '/struct '$${TYPE}' {/,/^}/s/^.*$$//' runtime.inc.tmp2 > runtime.inc.tmp3; \ - mv runtime.inc.tmp3 runtime.inc.tmp2; \ - done - sed -e 's/sigset/sigset_go/' runtime.inc.tmp2 > runtime.inc.tmp3 - $(SHELL) $(srcdir)/mvifdiff.sh runtime.inc.tmp3 runtime.inc - rm -f runtime.inc.tmp2 runtime.inc.tmp3 + $(SHELL) $(srcdir)/mkruntimeinc.sh + $(SHELL) $(srcdir)/mvifdiff.sh tmp-runtime.inc runtime.inc $(STAMP) $@ # Generate the list of go std packages that were included in libgo diff --git a/libgo/check-packages.txt b/libgo/check-packages.txt new file mode 100644 index 0000000..8ede851 --- /dev/null +++ b/libgo/check-packages.txt @@ -0,0 +1,162 @@ +archive/tar +archive/zip +bufio +bytes +cmd/go/internal/cache +cmd/go/internal/generate +cmd/go/internal/get +cmd/go/internal/load +cmd/go/internal/work +cmd/internal/buildid +cmd/internal/edit +cmd/internal/objabi +cmd/internal/test2json +cmd/vet/internal/cfg +compress/bzip2 +compress/flate +compress/gzip +compress/lzw +compress/zlib +container/heap +container/list +container/ring +context +crypto +crypto/aes +crypto/cipher +crypto/des +crypto/dsa +crypto/ecdsa +crypto/elliptic +crypto/hmac +crypto/md5 +crypto/rand +crypto/rc4 +crypto/rsa +crypto/sha1 +crypto/sha256 +crypto/sha512 +crypto/subtle +crypto/tls +crypto/x509 +database/sql +database/sql/driver +debug/dwarf +debug/elf +debug/macho +debug/pe +debug/plan9obj +debug/xcoff +encoding/ascii85 +encoding/asn1 +encoding/base32 +encoding/base64 +encoding/binary +encoding/csv +encoding/gob +encoding/hex +encoding/json +encoding/pem +encoding/xml +errors +expvar +flag +fmt +go/ast +go/build +go/constant +go/doc +go/format +go/importer +go/internal/gccgoimporter +go/internal/gcimporter +go/internal/srcimporter +go/parser +go/printer +go/scanner +go/token +go/types +golang_org/x/crypto/chacha20poly1305 +golang_org/x/crypto/chacha20poly1305/internal/chacha20 +golang_org/x/crypto/cryptobyte +golang_org/x/crypto/curve25519 +golang_org/x/crypto/poly1305 +golang_org/x/net/http2/hpack +golang_org/x/net/idna +golang_org/x/net/lex/httplex +golang_org/x/net/proxy +hash +hash/adler32 +hash/crc32 +hash/crc64 +hash/fnv +html +html/template +image +image/color +image/draw +image/jpeg +image/png +index/suffixarray +internal/poll +internal/singleflight +internal/trace +io +io/ioutil +log +log/syslog +math +math/big +math/bits +math/cmplx +math/rand +mime +mime/multipart +mime/quotedprintable +net +net/http +net/http/cgi +net/http/cookiejar +net/http/fcgi +net/http/httptest +net/http/httptrace +net/http/httputil +net/http/internal +net/internal/socktest +net/mail +net/rpc +net/rpc/jsonrpc +net/smtp +net/textproto +net/url +os +os/exec +os/signal +os/user +path +path/filepath +reflect +regexp +regexp/syntax +runtime +runtime/debug +runtime/internal/atomic +runtime/internal/sys +runtime/pprof +runtime/pprof/internal/profile +runtime/trace +sort +strconv +strings +sync +sync/atomic +syscall +testing/quick +text/scanner +text/tabwriter +text/template +text/template/parse +time +unicode +unicode/utf16 +unicode/utf8 diff --git a/libgo/gotool-packages.txt b/libgo/gotool-packages.txt new file mode 100644 index 0000000..012faf6 --- /dev/null +++ b/libgo/gotool-packages.txt @@ -0,0 +1,30 @@ +cmd/go/internal/base +cmd/go/internal/bug +cmd/go/internal/cache +cmd/go/internal/cfg +cmd/go/internal/clean +cmd/go/internal/cmdflag +cmd/go/internal/doc +cmd/go/internal/envcmd +cmd/go/internal/fix +cmd/go/internal/fmtcmd +cmd/go/internal/generate +cmd/go/internal/get +cmd/go/internal/help +cmd/go/internal/list +cmd/go/internal/load +cmd/go/internal/run +cmd/go/internal/str +cmd/go/internal/test +cmd/go/internal/tool +cmd/go/internal/version +cmd/go/internal/vet +cmd/go/internal/web +cmd/go/internal/work +cmd/internal/browser +cmd/internal/buildid +cmd/internal/edit +cmd/internal/objabi +cmd/internal/test2json +cmd/vet/internal/cfg +cmd/vet/internal/whitelist diff --git a/libgo/libgo-packages.txt b/libgo/libgo-packages.txt new file mode 100644 index 0000000..70c12ba --- /dev/null +++ b/libgo/libgo-packages.txt @@ -0,0 +1,177 @@ +archive/tar +archive/zip +bufio +bytes +compress/bzip2 +compress/flate +compress/gzip +compress/lzw +compress/zlib +container/heap +container/list +container/ring +context +crypto +crypto/aes +crypto/cipher +crypto/des +crypto/dsa +crypto/ecdsa +crypto/elliptic +crypto/hmac +crypto/internal/cipherhw +crypto/md5 +crypto/rand +crypto/rc4 +crypto/rsa +crypto/sha1 +crypto/sha256 +crypto/sha512 +crypto/subtle +crypto/tls +crypto/x509 +crypto/x509/pkix +database/sql +database/sql/driver +debug/dwarf +debug/elf +debug/gosym +debug/macho +debug/pe +debug/plan9obj +debug/xcoff +encoding +encoding/ascii85 +encoding/asn1 +encoding/base32 +encoding/base64 +encoding/binary +encoding/csv +encoding/gob +encoding/hex +encoding/json +encoding/pem +encoding/xml +errors +expvar +flag +fmt +go/ast +go/build +go/constant +go/doc +go/format +go/importer +go/internal/gccgoimporter +go/internal/gcimporter +go/internal/srcimporter +go/parser +go/printer +go/scanner +go/token +go/types +golang_org/x/crypto/chacha20poly1305 +golang_org/x/crypto/chacha20poly1305/internal/chacha20 +golang_org/x/crypto/cryptobyte +golang_org/x/crypto/cryptobyte/asn1 +golang_org/x/crypto/curve25519 +golang_org/x/crypto/poly1305 +golang_org/x/net/http2/hpack +golang_org/x/net/idna +golang_org/x/net/internal/nettest +golang_org/x/net/lex/httplex +golang_org/x/net/nettest +golang_org/x/net/proxy +golang_org/x/text/secure/bidirule +golang_org/x/text/transform +golang_org/x/text/unicode/bidi +golang_org/x/text/unicode/norm +golang_org/x/text/width +hash +hash/adler32 +hash/crc32 +hash/crc64 +hash/fnv +html +html/template +image +image/color +image/color/palette +image/draw +image/gif +image/internal/imageutil +image/jpeg +image/png +index/suffixarray +internal/nettrace +internal/poll +internal/race +internal/singleflight +internal/syscall/unix +internal/testenv +internal/testlog +internal/trace +io +io/ioutil +log +log/syslog +math +math/big +math/bits +math/cmplx +math/rand +mime +mime/multipart +mime/quotedprintable +net +net/http +net/http/cgi +net/http/cookiejar +net/http/fcgi +net/http/httptest +net/http/httptrace +net/http/httputil +net/http/internal +net/http/pprof +net/internal/socktest +net/mail +net/rpc +net/rpc/jsonrpc +net/smtp +net/textproto +net/url +os +os/exec +os/signal +os/signal/internal/pty +os/user +path +path/filepath +reflect +regexp +regexp/syntax +runtime +runtime/debug +runtime/internal/atomic +runtime/internal/sys +runtime/pprof +runtime/pprof/internal/profile +runtime/trace +sort +strconv +strings +sync +sync/atomic +syscall +testing +testing/internal/testdeps +testing/iotest +testing/quick +text/scanner +text/tabwriter +text/template +text/template/parse +time +unicode +unicode/utf16 +unicode/utf8 diff --git a/libgo/mkruntimeinc.sh b/libgo/mkruntimeinc.sh new file mode 100755 index 0000000..cd95595 --- /dev/null +++ b/libgo/mkruntimeinc.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +# Copyright 2018 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +# Create tmp-runtime.inc from runtime.inc.raw. + +IN=runtime.inc.raw +OUT=tmp-runtime.inc + +rm -f runtime.inc.tmp2 runtime.inc.tmp3 + +# _Complex_lock and _Reader_lock are Go translations of some AIX system +# types and should not be exported back to C +# semt is a Go translation of the C type sem_t; it fails to convert on +# some systems and need not be exported back to C. +# sigset conflicts with system type sigset on AIX, so we need to rename it + +grep -v "#define _" ${IN} | grep -v "#define [cm][01234] " | grep -v "#define empty " | grep -v "#define \\$" > runtime.inc.tmp2 +for pattern in '_[GP][a-z]' _Max _Lock _Sig _Trace _MHeap _Num +do + grep "#define $pattern" ${IN} >> runtime.inc.tmp2 +done +TYPES="_Complex_lock _Reader_lock semt" +for TYPE in $TYPES +do + sed -e '/struct '${TYPE}' {/,/^}/s/^.*$//' runtime.inc.tmp2 > runtime.inc.tmp3; + mv runtime.inc.tmp3 runtime.inc.tmp2 +done +sed -e 's/sigset/sigset_go/' runtime.inc.tmp2 > ${OUT} +rm -f runtime.inc.tmp2 runtime.inc.tmp3 +exit 0 -- cgit v1.1 From e1aeb9bc9e8704c99a6fb8a83983e42ea8967637 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 2 May 2018 22:01:22 +0000 Subject: runtime: remove unused stack.go We're never going to use stack.go for gccgo. Although a build tag keeps it from being built, even having it around can be confusing. Remove it. Reviewed-on: https://go-review.googlesource.com/40774 From-SVN: r259865 --- libgo/go/runtime/stack.go | 1229 --------------------------------------------- 1 file changed, 1229 deletions(-) delete mode 100644 libgo/go/runtime/stack.go (limited to 'libgo') diff --git a/libgo/go/runtime/stack.go b/libgo/go/runtime/stack.go deleted file mode 100644 index fd99e4d..0000000 --- a/libgo/go/runtime/stack.go +++ /dev/null @@ -1,1229 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -package runtime - -import ( - "runtime/internal/atomic" - "runtime/internal/sys" - "unsafe" -) - -/* -Stack layout parameters. -Included both by runtime (compiled via 6c) and linkers (compiled via gcc). - -The per-goroutine g->stackguard is set to point StackGuard bytes -above the bottom of the stack. Each function compares its stack -pointer against g->stackguard to check for overflow. To cut one -instruction from the check sequence for functions with tiny frames, -the stack is allowed to protrude StackSmall bytes below the stack -guard. Functions with large frames don't bother with the check and -always call morestack. The sequences are (for amd64, others are -similar): - - guard = g->stackguard - frame = function's stack frame size - argsize = size of function arguments (call + return) - - stack frame size <= StackSmall: - CMPQ guard, SP - JHI 3(PC) - MOVQ m->morearg, $(argsize << 32) - CALL morestack(SB) - - stack frame size > StackSmall but < StackBig - LEAQ (frame-StackSmall)(SP), R0 - CMPQ guard, R0 - JHI 3(PC) - MOVQ m->morearg, $(argsize << 32) - CALL morestack(SB) - - stack frame size >= StackBig: - MOVQ m->morearg, $((argsize << 32) | frame) - CALL morestack(SB) - -The bottom StackGuard - StackSmall bytes are important: there has -to be enough room to execute functions that refuse to check for -stack overflow, either because they need to be adjacent to the -actual caller's frame (deferproc) or because they handle the imminent -stack overflow (morestack). - -For example, deferproc might call malloc, which does one of the -above checks (without allocating a full frame), which might trigger -a call to morestack. This sequence needs to fit in the bottom -section of the stack. On amd64, morestack's frame is 40 bytes, and -deferproc's frame is 56 bytes. That fits well within the -StackGuard - StackSmall bytes at the bottom. -The linkers explore all possible call traces involving non-splitting -functions to make sure that this limit cannot be violated. -*/ - -const ( - // StackSystem is a number of additional bytes to add - // to each stack below the usual guard area for OS-specific - // purposes like signal handling. Used on Windows, Plan 9, - // and Darwin/ARM because they do not use a separate stack. - _StackSystem = sys.GoosWindows*512*sys.PtrSize + sys.GoosPlan9*512 + sys.GoosDarwin*sys.GoarchArm*1024 - - // The minimum size of stack used by Go code - _StackMin = 2048 - - // The minimum stack size to allocate. - // The hackery here rounds FixedStack0 up to a power of 2. - _FixedStack0 = _StackMin + _StackSystem - _FixedStack1 = _FixedStack0 - 1 - _FixedStack2 = _FixedStack1 | (_FixedStack1 >> 1) - _FixedStack3 = _FixedStack2 | (_FixedStack2 >> 2) - _FixedStack4 = _FixedStack3 | (_FixedStack3 >> 4) - _FixedStack5 = _FixedStack4 | (_FixedStack4 >> 8) - _FixedStack6 = _FixedStack5 | (_FixedStack5 >> 16) - _FixedStack = _FixedStack6 + 1 - - // Functions that need frames bigger than this use an extra - // instruction to do the stack split check, to avoid overflow - // in case SP - framesize wraps below zero. - // This value can be no bigger than the size of the unmapped - // space at zero. - _StackBig = 4096 - - // The stack guard is a pointer this many bytes above the - // bottom of the stack. - _StackGuard = 880*sys.StackGuardMultiplier + _StackSystem - - // After a stack split check the SP is allowed to be this - // many bytes below the stack guard. This saves an instruction - // in the checking sequence for tiny frames. - _StackSmall = 128 - - // The maximum number of bytes that a chain of NOSPLIT - // functions can use. - _StackLimit = _StackGuard - _StackSystem - _StackSmall -) - -// Goroutine preemption request. -// Stored into g->stackguard0 to cause split stack check failure. -// Must be greater than any real sp. -// 0xfffffade in hex. -const ( - _StackPreempt = uintptrMask & -1314 - _StackFork = uintptrMask & -1234 -) - -const ( - // stackDebug == 0: no logging - // == 1: logging of per-stack operations - // == 2: logging of per-frame operations - // == 3: logging of per-word updates - // == 4: logging of per-word reads - stackDebug = 0 - stackFromSystem = 0 // allocate stacks from system memory instead of the heap - stackFaultOnFree = 0 // old stacks are mapped noaccess to detect use after free - stackPoisonCopy = 0 // fill stack that should not be accessed with garbage, to detect bad dereferences during copy - - stackCache = 1 - - // check the BP links during traceback. - debugCheckBP = false -) - -const ( - uintptrMask = 1<<(8*sys.PtrSize) - 1 - - // Goroutine preemption request. - // Stored into g->stackguard0 to cause split stack check failure. - // Must be greater than any real sp. - // 0xfffffade in hex. - stackPreempt = uintptrMask & -1314 - - // Thread is forking. - // Stored into g->stackguard0 to cause split stack check failure. - // Must be greater than any real sp. - stackFork = uintptrMask & -1234 -) - -// Global pool of spans that have free stacks. -// Stacks are assigned an order according to size. -// order = log_2(size/FixedStack) -// There is a free list for each order. -// TODO: one lock per order? -var stackpool [_NumStackOrders]mSpanList -var stackpoolmu mutex - -// Global pool of large stack spans. -var stackLarge struct { - lock mutex - free [_MHeapMap_Bits]mSpanList // free lists by log_2(s.npages) -} - -func stackinit() { - if _StackCacheSize&_PageMask != 0 { - throw("cache size must be a multiple of page size") - } - for i := range stackpool { - stackpool[i].init() - } - for i := range stackLarge.free { - stackLarge.free[i].init() - } -} - -// stacklog2 returns ⌊log_2(n)⌋. -func stacklog2(n uintptr) int { - log2 := 0 - for n > 1 { - n >>= 1 - log2++ - } - return log2 -} - -// Allocates a stack from the free pool. Must be called with -// stackpoolmu held. -func stackpoolalloc(order uint8) gclinkptr { - list := &stackpool[order] - s := list.first - if s == nil { - // no free stacks. Allocate another span worth. - s = mheap_.allocStack(_StackCacheSize >> _PageShift) - if s == nil { - throw("out of memory") - } - if s.allocCount != 0 { - throw("bad allocCount") - } - if s.stackfreelist.ptr() != nil { - throw("bad stackfreelist") - } - for i := uintptr(0); i < _StackCacheSize; i += _FixedStack << order { - x := gclinkptr(s.base() + i) - x.ptr().next = s.stackfreelist - s.stackfreelist = x - } - list.insert(s) - } - x := s.stackfreelist - if x.ptr() == nil { - throw("span has no free stacks") - } - s.stackfreelist = x.ptr().next - s.allocCount++ - if s.stackfreelist.ptr() == nil { - // all stacks in s are allocated. - list.remove(s) - } - return x -} - -// Adds stack x to the free pool. Must be called with stackpoolmu held. -func stackpoolfree(x gclinkptr, order uint8) { - s := mheap_.lookup(unsafe.Pointer(x)) - if s.state != _MSpanStack { - throw("freeing stack not in a stack span") - } - if s.stackfreelist.ptr() == nil { - // s will now have a free stack - stackpool[order].insert(s) - } - x.ptr().next = s.stackfreelist - s.stackfreelist = x - s.allocCount-- - if gcphase == _GCoff && s.allocCount == 0 { - // Span is completely free. Return it to the heap - // immediately if we're sweeping. - // - // If GC is active, we delay the free until the end of - // GC to avoid the following type of situation: - // - // 1) GC starts, scans a SudoG but does not yet mark the SudoG.elem pointer - // 2) The stack that pointer points to is copied - // 3) The old stack is freed - // 4) The containing span is marked free - // 5) GC attempts to mark the SudoG.elem pointer. The - // marking fails because the pointer looks like a - // pointer into a free span. - // - // By not freeing, we prevent step #4 until GC is done. - stackpool[order].remove(s) - s.stackfreelist = 0 - mheap_.freeStack(s) - } -} - -// stackcacherefill/stackcacherelease implement a global pool of stack segments. -// The pool is required to prevent unlimited growth of per-thread caches. -// -//go:systemstack -func stackcacherefill(c *mcache, order uint8) { - if stackDebug >= 1 { - print("stackcacherefill order=", order, "\n") - } - - // Grab some stacks from the global cache. - // Grab half of the allowed capacity (to prevent thrashing). - var list gclinkptr - var size uintptr - lock(&stackpoolmu) - for size < _StackCacheSize/2 { - x := stackpoolalloc(order) - x.ptr().next = list - list = x - size += _FixedStack << order - } - unlock(&stackpoolmu) - c.stackcache[order].list = list - c.stackcache[order].size = size -} - -//go:systemstack -func stackcacherelease(c *mcache, order uint8) { - if stackDebug >= 1 { - print("stackcacherelease order=", order, "\n") - } - x := c.stackcache[order].list - size := c.stackcache[order].size - lock(&stackpoolmu) - for size > _StackCacheSize/2 { - y := x.ptr().next - stackpoolfree(x, order) - x = y - size -= _FixedStack << order - } - unlock(&stackpoolmu) - c.stackcache[order].list = x - c.stackcache[order].size = size -} - -//go:systemstack -func stackcache_clear(c *mcache) { - if stackDebug >= 1 { - print("stackcache clear\n") - } - lock(&stackpoolmu) - for order := uint8(0); order < _NumStackOrders; order++ { - x := c.stackcache[order].list - for x.ptr() != nil { - y := x.ptr().next - stackpoolfree(x, order) - x = y - } - c.stackcache[order].list = 0 - c.stackcache[order].size = 0 - } - unlock(&stackpoolmu) -} - -// stackalloc allocates an n byte stack. -// -// stackalloc must run on the system stack because it uses per-P -// resources and must not split the stack. -// -//go:systemstack -func stackalloc(n uint32) (stack, []stkbar) { - // Stackalloc must be called on scheduler stack, so that we - // never try to grow the stack during the code that stackalloc runs. - // Doing so would cause a deadlock (issue 1547). - thisg := getg() - if thisg != thisg.m.g0 { - throw("stackalloc not on scheduler stack") - } - if n&(n-1) != 0 { - throw("stack size not a power of 2") - } - if stackDebug >= 1 { - print("stackalloc ", n, "\n") - } - - // Compute the size of stack barrier array. - maxstkbar := gcMaxStackBarriers(int(n)) - nstkbar := unsafe.Sizeof(stkbar{}) * uintptr(maxstkbar) - var stkbarSlice slice - - if debug.efence != 0 || stackFromSystem != 0 { - v := sysAlloc(round(uintptr(n), _PageSize), &memstats.stacks_sys) - if v == nil { - throw("out of memory (stackalloc)") - } - top := uintptr(n) - nstkbar - if maxstkbar != 0 { - stkbarSlice = slice{add(v, top), 0, maxstkbar} - } - return stack{uintptr(v), uintptr(v) + top}, *(*[]stkbar)(unsafe.Pointer(&stkbarSlice)) - } - - // Small stacks are allocated with a fixed-size free-list allocator. - // If we need a stack of a bigger size, we fall back on allocating - // a dedicated span. - var v unsafe.Pointer - if stackCache != 0 && n < _FixedStack<<_NumStackOrders && n < _StackCacheSize { - order := uint8(0) - n2 := n - for n2 > _FixedStack { - order++ - n2 >>= 1 - } - var x gclinkptr - c := thisg.m.mcache - if c == nil || thisg.m.preemptoff != "" || thisg.m.helpgc != 0 { - // c == nil can happen in the guts of exitsyscall or - // procresize. Just get a stack from the global pool. - // Also don't touch stackcache during gc - // as it's flushed concurrently. - lock(&stackpoolmu) - x = stackpoolalloc(order) - unlock(&stackpoolmu) - } else { - x = c.stackcache[order].list - if x.ptr() == nil { - stackcacherefill(c, order) - x = c.stackcache[order].list - } - c.stackcache[order].list = x.ptr().next - c.stackcache[order].size -= uintptr(n) - } - v = unsafe.Pointer(x) - } else { - var s *mspan - npage := uintptr(n) >> _PageShift - log2npage := stacklog2(npage) - - // Try to get a stack from the large stack cache. - lock(&stackLarge.lock) - if !stackLarge.free[log2npage].isEmpty() { - s = stackLarge.free[log2npage].first - stackLarge.free[log2npage].remove(s) - } - unlock(&stackLarge.lock) - - if s == nil { - // Allocate a new stack from the heap. - s = mheap_.allocStack(npage) - if s == nil { - throw("out of memory") - } - } - v = unsafe.Pointer(s.base()) - } - - if raceenabled { - racemalloc(v, uintptr(n)) - } - if msanenabled { - msanmalloc(v, uintptr(n)) - } - if stackDebug >= 1 { - print(" allocated ", v, "\n") - } - top := uintptr(n) - nstkbar - if maxstkbar != 0 { - stkbarSlice = slice{add(v, top), 0, maxstkbar} - } - return stack{uintptr(v), uintptr(v) + top}, *(*[]stkbar)(unsafe.Pointer(&stkbarSlice)) -} - -// stackfree frees an n byte stack allocation at stk. -// -// stackfree must run on the system stack because it uses per-P -// resources and must not split the stack. -// -//go:systemstack -func stackfree(stk stack, n uintptr) { - gp := getg() - v := unsafe.Pointer(stk.lo) - if n&(n-1) != 0 { - throw("stack not a power of 2") - } - if stk.lo+n < stk.hi { - throw("bad stack size") - } - if stackDebug >= 1 { - println("stackfree", v, n) - memclrNoHeapPointers(v, n) // for testing, clobber stack data - } - if debug.efence != 0 || stackFromSystem != 0 { - if debug.efence != 0 || stackFaultOnFree != 0 { - sysFault(v, n) - } else { - sysFree(v, n, &memstats.stacks_sys) - } - return - } - if msanenabled { - msanfree(v, n) - } - if stackCache != 0 && n < _FixedStack<<_NumStackOrders && n < _StackCacheSize { - order := uint8(0) - n2 := n - for n2 > _FixedStack { - order++ - n2 >>= 1 - } - x := gclinkptr(v) - c := gp.m.mcache - if c == nil || gp.m.preemptoff != "" || gp.m.helpgc != 0 { - lock(&stackpoolmu) - stackpoolfree(x, order) - unlock(&stackpoolmu) - } else { - if c.stackcache[order].size >= _StackCacheSize { - stackcacherelease(c, order) - } - x.ptr().next = c.stackcache[order].list - c.stackcache[order].list = x - c.stackcache[order].size += n - } - } else { - s := mheap_.lookup(v) - if s.state != _MSpanStack { - println(hex(s.base()), v) - throw("bad span state") - } - if gcphase == _GCoff { - // Free the stack immediately if we're - // sweeping. - mheap_.freeStack(s) - } else { - // If the GC is running, we can't return a - // stack span to the heap because it could be - // reused as a heap span, and this state - // change would race with GC. Add it to the - // large stack cache instead. - log2npage := stacklog2(s.npages) - lock(&stackLarge.lock) - stackLarge.free[log2npage].insert(s) - unlock(&stackLarge.lock) - } - } -} - -var maxstacksize uintptr = 1 << 20 // enough until runtime.main sets it for real - -var ptrnames = []string{ - 0: "scalar", - 1: "ptr", -} - -// Stack frame layout -// -// (x86) -// +------------------+ -// | args from caller | -// +------------------+ <- frame->argp -// | return address | -// +------------------+ -// | caller's BP (*) | (*) if framepointer_enabled && varp < sp -// +------------------+ <- frame->varp -// | locals | -// +------------------+ -// | args to callee | -// +------------------+ <- frame->sp -// -// (arm) -// +------------------+ -// | args from caller | -// +------------------+ <- frame->argp -// | caller's retaddr | -// +------------------+ <- frame->varp -// | locals | -// +------------------+ -// | args to callee | -// +------------------+ -// | return address | -// +------------------+ <- frame->sp - -type adjustinfo struct { - old stack - delta uintptr // ptr distance from old to new stack (newbase - oldbase) - cache pcvalueCache - - // sghi is the highest sudog.elem on the stack. - sghi uintptr -} - -// Adjustpointer checks whether *vpp is in the old stack described by adjinfo. -// If so, it rewrites *vpp to point into the new stack. -func adjustpointer(adjinfo *adjustinfo, vpp unsafe.Pointer) { - pp := (*uintptr)(vpp) - p := *pp - if stackDebug >= 4 { - print(" ", pp, ":", hex(p), "\n") - } - if adjinfo.old.lo <= p && p < adjinfo.old.hi { - *pp = p + adjinfo.delta - if stackDebug >= 3 { - print(" adjust ptr ", pp, ":", hex(p), " -> ", hex(*pp), "\n") - } - } -} - -// Information from the compiler about the layout of stack frames. -type bitvector struct { - n int32 // # of bits - bytedata *uint8 -} - -type gobitvector struct { - n uintptr - bytedata []uint8 -} - -func gobv(bv bitvector) gobitvector { - return gobitvector{ - uintptr(bv.n), - (*[1 << 30]byte)(unsafe.Pointer(bv.bytedata))[:(bv.n+7)/8], - } -} - -func ptrbit(bv *gobitvector, i uintptr) uint8 { - return (bv.bytedata[i/8] >> (i % 8)) & 1 -} - -// bv describes the memory starting at address scanp. -// Adjust any pointers contained therein. -func adjustpointers(scanp unsafe.Pointer, cbv *bitvector, adjinfo *adjustinfo, f *_func) { - bv := gobv(*cbv) - minp := adjinfo.old.lo - maxp := adjinfo.old.hi - delta := adjinfo.delta - num := bv.n - // If this frame might contain channel receive slots, use CAS - // to adjust pointers. If the slot hasn't been received into - // yet, it may contain stack pointers and a concurrent send - // could race with adjusting those pointers. (The sent value - // itself can never contain stack pointers.) - useCAS := uintptr(scanp) < adjinfo.sghi - for i := uintptr(0); i < num; i++ { - if stackDebug >= 4 { - print(" ", add(scanp, i*sys.PtrSize), ":", ptrnames[ptrbit(&bv, i)], ":", hex(*(*uintptr)(add(scanp, i*sys.PtrSize))), " # ", i, " ", bv.bytedata[i/8], "\n") - } - if ptrbit(&bv, i) == 1 { - pp := (*uintptr)(add(scanp, i*sys.PtrSize)) - retry: - p := *pp - if f != nil && 0 < p && p < minLegalPointer && debug.invalidptr != 0 { - // Looks like a junk value in a pointer slot. - // Live analysis wrong? - getg().m.traceback = 2 - print("runtime: bad pointer in frame ", funcname(f), " at ", pp, ": ", hex(p), "\n") - throw("invalid pointer found on stack") - } - if minp <= p && p < maxp { - if stackDebug >= 3 { - print("adjust ptr ", hex(p), " ", funcname(f), "\n") - } - if useCAS { - ppu := (*unsafe.Pointer)(unsafe.Pointer(pp)) - if !atomic.Casp1(ppu, unsafe.Pointer(p), unsafe.Pointer(p+delta)) { - goto retry - } - } else { - *pp = p + delta - } - } - } - } -} - -// Note: the argument/return area is adjusted by the callee. -func adjustframe(frame *stkframe, arg unsafe.Pointer) bool { - adjinfo := (*adjustinfo)(arg) - targetpc := frame.continpc - if targetpc == 0 { - // Frame is dead. - return true - } - f := frame.fn - if stackDebug >= 2 { - print(" adjusting ", funcname(f), " frame=[", hex(frame.sp), ",", hex(frame.fp), "] pc=", hex(frame.pc), " continpc=", hex(frame.continpc), "\n") - } - if f.entry == systemstack_switchPC { - // A special routine at the bottom of stack of a goroutine that does an systemstack call. - // We will allow it to be copied even though we don't - // have full GC info for it (because it is written in asm). - return true - } - if targetpc != f.entry { - targetpc-- - } - pcdata := pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, &adjinfo.cache) - if pcdata == -1 { - pcdata = 0 // in prologue - } - - // Adjust local variables if stack frame has been allocated. - size := frame.varp - frame.sp - var minsize uintptr - switch sys.ArchFamily { - case sys.ARM64: - minsize = sys.SpAlign - default: - minsize = sys.MinFrameSize - } - if size > minsize { - var bv bitvector - stackmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps)) - if stackmap == nil || stackmap.n <= 0 { - print("runtime: frame ", funcname(f), " untyped locals ", hex(frame.varp-size), "+", hex(size), "\n") - throw("missing stackmap") - } - // Locals bitmap information, scan just the pointers in locals. - if pcdata < 0 || pcdata >= stackmap.n { - // don't know where we are - print("runtime: pcdata is ", pcdata, " and ", stackmap.n, " locals stack map entries for ", funcname(f), " (targetpc=", targetpc, ")\n") - throw("bad symbol table") - } - bv = stackmapdata(stackmap, pcdata) - size = uintptr(bv.n) * sys.PtrSize - if stackDebug >= 3 { - print(" locals ", pcdata, "/", stackmap.n, " ", size/sys.PtrSize, " words ", bv.bytedata, "\n") - } - adjustpointers(unsafe.Pointer(frame.varp-size), &bv, adjinfo, f) - } - - // Adjust saved base pointer if there is one. - if sys.ArchFamily == sys.AMD64 && frame.argp-frame.varp == 2*sys.RegSize { - if !framepointer_enabled { - print("runtime: found space for saved base pointer, but no framepointer experiment\n") - print("argp=", hex(frame.argp), " varp=", hex(frame.varp), "\n") - throw("bad frame layout") - } - if stackDebug >= 3 { - print(" saved bp\n") - } - if debugCheckBP { - // Frame pointers should always point to the next higher frame on - // the Go stack (or be nil, for the top frame on the stack). - bp := *(*uintptr)(unsafe.Pointer(frame.varp)) - if bp != 0 && (bp < adjinfo.old.lo || bp >= adjinfo.old.hi) { - println("runtime: found invalid frame pointer") - print("bp=", hex(bp), " min=", hex(adjinfo.old.lo), " max=", hex(adjinfo.old.hi), "\n") - throw("bad frame pointer") - } - } - adjustpointer(adjinfo, unsafe.Pointer(frame.varp)) - } - - // Adjust arguments. - if frame.arglen > 0 { - var bv bitvector - if frame.argmap != nil { - bv = *frame.argmap - } else { - stackmap := (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps)) - if stackmap == nil || stackmap.n <= 0 { - print("runtime: frame ", funcname(f), " untyped args ", frame.argp, "+", frame.arglen, "\n") - throw("missing stackmap") - } - if pcdata < 0 || pcdata >= stackmap.n { - // don't know where we are - print("runtime: pcdata is ", pcdata, " and ", stackmap.n, " args stack map entries for ", funcname(f), " (targetpc=", targetpc, ")\n") - throw("bad symbol table") - } - bv = stackmapdata(stackmap, pcdata) - } - if stackDebug >= 3 { - print(" args\n") - } - adjustpointers(unsafe.Pointer(frame.argp), &bv, adjinfo, nil) - } - return true -} - -func adjustctxt(gp *g, adjinfo *adjustinfo) { - adjustpointer(adjinfo, unsafe.Pointer(&gp.sched.ctxt)) - if !framepointer_enabled { - return - } - if debugCheckBP { - bp := gp.sched.bp - if bp != 0 && (bp < adjinfo.old.lo || bp >= adjinfo.old.hi) { - println("runtime: found invalid top frame pointer") - print("bp=", hex(bp), " min=", hex(adjinfo.old.lo), " max=", hex(adjinfo.old.hi), "\n") - throw("bad top frame pointer") - } - } - adjustpointer(adjinfo, unsafe.Pointer(&gp.sched.bp)) -} - -func adjustdefers(gp *g, adjinfo *adjustinfo) { - // Adjust defer argument blocks the same way we adjust active stack frames. - tracebackdefers(gp, adjustframe, noescape(unsafe.Pointer(adjinfo))) - - // Adjust pointers in the Defer structs. - // Defer structs themselves are never on the stack. - for d := gp._defer; d != nil; d = d.link { - adjustpointer(adjinfo, unsafe.Pointer(&d.fn)) - adjustpointer(adjinfo, unsafe.Pointer(&d.sp)) - adjustpointer(adjinfo, unsafe.Pointer(&d._panic)) - } -} - -func adjustpanics(gp *g, adjinfo *adjustinfo) { - // Panics are on stack and already adjusted. - // Update pointer to head of list in G. - adjustpointer(adjinfo, unsafe.Pointer(&gp._panic)) -} - -func adjustsudogs(gp *g, adjinfo *adjustinfo) { - // the data elements pointed to by a SudoG structure - // might be in the stack. - for s := gp.waiting; s != nil; s = s.waitlink { - adjustpointer(adjinfo, unsafe.Pointer(&s.elem)) - adjustpointer(adjinfo, unsafe.Pointer(&s.selectdone)) - } -} - -func adjuststkbar(gp *g, adjinfo *adjustinfo) { - for i := int(gp.stkbarPos); i < len(gp.stkbar); i++ { - adjustpointer(adjinfo, unsafe.Pointer(&gp.stkbar[i].savedLRPtr)) - } -} - -func fillstack(stk stack, b byte) { - for p := stk.lo; p < stk.hi; p++ { - *(*byte)(unsafe.Pointer(p)) = b - } -} - -func findsghi(gp *g, stk stack) uintptr { - var sghi uintptr - for sg := gp.waiting; sg != nil; sg = sg.waitlink { - p := uintptr(sg.elem) + uintptr(sg.c.elemsize) - if stk.lo <= p && p < stk.hi && p > sghi { - sghi = p - } - p = uintptr(unsafe.Pointer(sg.selectdone)) + unsafe.Sizeof(sg.selectdone) - if stk.lo <= p && p < stk.hi && p > sghi { - sghi = p - } - } - return sghi -} - -// syncadjustsudogs adjusts gp's sudogs and copies the part of gp's -// stack they refer to while synchronizing with concurrent channel -// operations. It returns the number of bytes of stack copied. -func syncadjustsudogs(gp *g, used uintptr, adjinfo *adjustinfo) uintptr { - if gp.waiting == nil { - return 0 - } - - // Lock channels to prevent concurrent send/receive. - // It's important that we *only* do this for async - // copystack; otherwise, gp may be in the middle of - // putting itself on wait queues and this would - // self-deadlock. - var lastc *hchan - for sg := gp.waiting; sg != nil; sg = sg.waitlink { - if sg.c != lastc { - lock(&sg.c.lock) - } - lastc = sg.c - } - - // Adjust sudogs. - adjustsudogs(gp, adjinfo) - - // Copy the part of the stack the sudogs point in to - // while holding the lock to prevent races on - // send/receive slots. - var sgsize uintptr - if adjinfo.sghi != 0 { - oldBot := adjinfo.old.hi - used - newBot := oldBot + adjinfo.delta - sgsize = adjinfo.sghi - oldBot - memmove(unsafe.Pointer(newBot), unsafe.Pointer(oldBot), sgsize) - } - - // Unlock channels. - lastc = nil - for sg := gp.waiting; sg != nil; sg = sg.waitlink { - if sg.c != lastc { - unlock(&sg.c.lock) - } - lastc = sg.c - } - - return sgsize -} - -// Copies gp's stack to a new stack of a different size. -// Caller must have changed gp status to Gcopystack. -// -// If sync is true, this is a self-triggered stack growth and, in -// particular, no other G may be writing to gp's stack (e.g., via a -// channel operation). If sync is false, copystack protects against -// concurrent channel operations. -func copystack(gp *g, newsize uintptr, sync bool) { - if gp.syscallsp != 0 { - throw("stack growth not allowed in system call") - } - old := gp.stack - if old.lo == 0 { - throw("nil stackbase") - } - used := old.hi - gp.sched.sp - - // allocate new stack - new, newstkbar := stackalloc(uint32(newsize)) - if stackPoisonCopy != 0 { - fillstack(new, 0xfd) - } - if stackDebug >= 1 { - print("copystack gp=", gp, " [", hex(old.lo), " ", hex(old.hi-used), " ", hex(old.hi), "]/", gp.stackAlloc, " -> [", hex(new.lo), " ", hex(new.hi-used), " ", hex(new.hi), "]/", newsize, "\n") - } - - // Compute adjustment. - var adjinfo adjustinfo - adjinfo.old = old - adjinfo.delta = new.hi - old.hi - - // Adjust sudogs, synchronizing with channel ops if necessary. - ncopy := used - if sync { - adjustsudogs(gp, &adjinfo) - } else { - // sudogs can point in to the stack. During concurrent - // shrinking, these areas may be written to. Find the - // highest such pointer so we can handle everything - // there and below carefully. (This shouldn't be far - // from the bottom of the stack, so there's little - // cost in handling everything below it carefully.) - adjinfo.sghi = findsghi(gp, old) - - // Synchronize with channel ops and copy the part of - // the stack they may interact with. - ncopy -= syncadjustsudogs(gp, used, &adjinfo) - } - - // Copy the stack (or the rest of it) to the new location - memmove(unsafe.Pointer(new.hi-ncopy), unsafe.Pointer(old.hi-ncopy), ncopy) - - // Disallow sigprof scans of this stack and block if there's - // one in progress. - gcLockStackBarriers(gp) - - // Adjust remaining structures that have pointers into stacks. - // We have to do most of these before we traceback the new - // stack because gentraceback uses them. - adjustctxt(gp, &adjinfo) - adjustdefers(gp, &adjinfo) - adjustpanics(gp, &adjinfo) - adjuststkbar(gp, &adjinfo) - if adjinfo.sghi != 0 { - adjinfo.sghi += adjinfo.delta - } - - // copy old stack barriers to new stack barrier array - newstkbar = newstkbar[:len(gp.stkbar)] - copy(newstkbar, gp.stkbar) - - // Swap out old stack for new one - gp.stack = new - gp.stackguard0 = new.lo + _StackGuard // NOTE: might clobber a preempt request - gp.sched.sp = new.hi - used - oldsize := gp.stackAlloc - gp.stackAlloc = newsize - gp.stkbar = newstkbar - gp.stktopsp += adjinfo.delta - - // Adjust pointers in the new stack. - gentraceback(^uintptr(0), ^uintptr(0), 0, gp, 0, nil, 0x7fffffff, adjustframe, noescape(unsafe.Pointer(&adjinfo)), 0) - - gcUnlockStackBarriers(gp) - - // free old stack - if stackPoisonCopy != 0 { - fillstack(old, 0xfc) - } - stackfree(old, oldsize) -} - -// round x up to a power of 2. -func round2(x int32) int32 { - s := uint(0) - for 1<atomicstatus will be Grunning or Gscanrunning upon entry. -// If the GC is trying to stop this g then it will set preemptscan to true. -// -// ctxt is the value of the context register on morestack. newstack -// will write it to g.sched.ctxt. -func newstack(ctxt unsafe.Pointer) { - thisg := getg() - // TODO: double check all gp. shouldn't be getg(). - if thisg.m.morebuf.g.ptr().stackguard0 == stackFork { - throw("stack growth after fork") - } - if thisg.m.morebuf.g.ptr() != thisg.m.curg { - print("runtime: newstack called from g=", hex(thisg.m.morebuf.g), "\n"+"\tm=", thisg.m, " m->curg=", thisg.m.curg, " m->g0=", thisg.m.g0, " m->gsignal=", thisg.m.gsignal, "\n") - morebuf := thisg.m.morebuf - traceback(morebuf.pc, morebuf.sp, morebuf.lr, morebuf.g.ptr()) - throw("runtime: wrong goroutine in newstack") - } - - gp := thisg.m.curg - // Write ctxt to gp.sched. We do this here instead of in - // morestack so it has the necessary write barrier. - gp.sched.ctxt = ctxt - - if thisg.m.curg.throwsplit { - // Update syscallsp, syscallpc in case traceback uses them. - morebuf := thisg.m.morebuf - gp.syscallsp = morebuf.sp - gp.syscallpc = morebuf.pc - print("runtime: newstack sp=", hex(gp.sched.sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n", - "\tmorebuf={pc:", hex(morebuf.pc), " sp:", hex(morebuf.sp), " lr:", hex(morebuf.lr), "}\n", - "\tsched={pc:", hex(gp.sched.pc), " sp:", hex(gp.sched.sp), " lr:", hex(gp.sched.lr), " ctxt:", gp.sched.ctxt, "}\n") - - traceback(morebuf.pc, morebuf.sp, morebuf.lr, gp) - throw("runtime: stack split at bad time") - } - - morebuf := thisg.m.morebuf - thisg.m.morebuf.pc = 0 - thisg.m.morebuf.lr = 0 - thisg.m.morebuf.sp = 0 - thisg.m.morebuf.g = 0 - - // NOTE: stackguard0 may change underfoot, if another thread - // is about to try to preempt gp. Read it just once and use that same - // value now and below. - preempt := atomic.Loaduintptr(&gp.stackguard0) == stackPreempt - - // Be conservative about where we preempt. - // We are interested in preempting user Go code, not runtime code. - // If we're holding locks, mallocing, or preemption is disabled, don't - // preempt. - // This check is very early in newstack so that even the status change - // from Grunning to Gwaiting and back doesn't happen in this case. - // That status change by itself can be viewed as a small preemption, - // because the GC might change Gwaiting to Gscanwaiting, and then - // this goroutine has to wait for the GC to finish before continuing. - // If the GC is in some way dependent on this goroutine (for example, - // it needs a lock held by the goroutine), that small preemption turns - // into a real deadlock. - if preempt { - if thisg.m.locks != 0 || thisg.m.mallocing != 0 || thisg.m.preemptoff != "" || thisg.m.p.ptr().status != _Prunning { - // Let the goroutine keep running for now. - // gp->preempt is set, so it will be preempted next time. - gp.stackguard0 = gp.stack.lo + _StackGuard - gogo(&gp.sched) // never return - } - } - - if gp.stack.lo == 0 { - throw("missing stack in newstack") - } - sp := gp.sched.sp - if sys.ArchFamily == sys.AMD64 || sys.ArchFamily == sys.I386 { - // The call to morestack cost a word. - sp -= sys.PtrSize - } - if stackDebug >= 1 || sp < gp.stack.lo { - print("runtime: newstack sp=", hex(sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n", - "\tmorebuf={pc:", hex(morebuf.pc), " sp:", hex(morebuf.sp), " lr:", hex(morebuf.lr), "}\n", - "\tsched={pc:", hex(gp.sched.pc), " sp:", hex(gp.sched.sp), " lr:", hex(gp.sched.lr), " ctxt:", gp.sched.ctxt, "}\n") - } - if sp < gp.stack.lo { - print("runtime: gp=", gp, ", gp->status=", hex(readgstatus(gp)), "\n ") - print("runtime: split stack overflow: ", hex(sp), " < ", hex(gp.stack.lo), "\n") - throw("runtime: split stack overflow") - } - - if preempt { - if gp == thisg.m.g0 { - throw("runtime: preempt g0") - } - if thisg.m.p == 0 && thisg.m.locks == 0 { - throw("runtime: g is running but p is not") - } - // Synchronize with scang. - casgstatus(gp, _Grunning, _Gwaiting) - if gp.preemptscan { - for !castogscanstatus(gp, _Gwaiting, _Gscanwaiting) { - // Likely to be racing with the GC as - // it sees a _Gwaiting and does the - // stack scan. If so, gcworkdone will - // be set and gcphasework will simply - // return. - } - if !gp.gcscandone { - // gcw is safe because we're on the - // system stack. - gcw := &gp.m.p.ptr().gcw - scanstack(gp, gcw) - if gcBlackenPromptly { - gcw.dispose() - } - gp.gcscandone = true - } - gp.preemptscan = false - gp.preempt = false - casfrom_Gscanstatus(gp, _Gscanwaiting, _Gwaiting) - // This clears gcscanvalid. - casgstatus(gp, _Gwaiting, _Grunning) - gp.stackguard0 = gp.stack.lo + _StackGuard - gogo(&gp.sched) // never return - } - - // Act like goroutine called runtime.Gosched. - casgstatus(gp, _Gwaiting, _Grunning) - gopreempt_m(gp) // never return - } - - // Allocate a bigger segment and move the stack. - oldsize := int(gp.stackAlloc) - newsize := oldsize * 2 - if uintptr(newsize) > maxstacksize { - print("runtime: goroutine stack exceeds ", maxstacksize, "-byte limit\n") - throw("stack overflow") - } - - // The goroutine must be executing in order to call newstack, - // so it must be Grunning (or Gscanrunning). - casgstatus(gp, _Grunning, _Gcopystack) - - // The concurrent GC will not scan the stack while we are doing the copy since - // the gp is in a Gcopystack status. - copystack(gp, uintptr(newsize), true) - if stackDebug >= 1 { - print("stack grow done\n") - } - casgstatus(gp, _Gcopystack, _Grunning) - gogo(&gp.sched) -} - -//go:nosplit -func nilfunc() { - *(*uint8)(nil) = 0 -} - -// adjust Gobuf as if it executed a call to fn -// and then did an immediate gosave. -func gostartcallfn(gobuf *gobuf, fv *funcval) { - var fn unsafe.Pointer - if fv != nil { - fn = unsafe.Pointer(fv.fn) - } else { - fn = unsafe.Pointer(funcPC(nilfunc)) - } - gostartcall(gobuf, fn, unsafe.Pointer(fv)) -} - -// Maybe shrink the stack being used by gp. -// Called at garbage collection time. -// gp must be stopped, but the world need not be. -func shrinkstack(gp *g) { - gstatus := readgstatus(gp) - if gstatus&^_Gscan == _Gdead { - if gp.stack.lo != 0 { - // Free whole stack - it will get reallocated - // if G is used again. - stackfree(gp.stack, gp.stackAlloc) - gp.stack.lo = 0 - gp.stack.hi = 0 - gp.stkbar = nil - gp.stkbarPos = 0 - } - return - } - if gp.stack.lo == 0 { - throw("missing stack in shrinkstack") - } - if gstatus&_Gscan == 0 { - throw("bad status in shrinkstack") - } - - if debug.gcshrinkstackoff > 0 { - return - } - if gp.startpc == gcBgMarkWorkerPC { - // We're not allowed to shrink the gcBgMarkWorker - // stack (see gcBgMarkWorker for explanation). - return - } - - oldsize := gp.stackAlloc - newsize := oldsize / 2 - // Don't shrink the allocation below the minimum-sized stack - // allocation. - if newsize < _FixedStack { - return - } - // Compute how much of the stack is currently in use and only - // shrink the stack if gp is using less than a quarter of its - // current stack. The currently used stack includes everything - // down to the SP plus the stack guard space that ensures - // there's room for nosplit functions. - avail := gp.stack.hi - gp.stack.lo - if used := gp.stack.hi - gp.sched.sp + _StackLimit; used >= avail/4 { - return - } - - // We can't copy the stack if we're in a syscall. - // The syscall might have pointers into the stack. - if gp.syscallsp != 0 { - return - } - if sys.GoosWindows != 0 && gp.m != nil && gp.m.libcallsp != 0 { - return - } - - if stackDebug > 0 { - print("shrinking stack ", oldsize, "->", newsize, "\n") - } - - copystack(gp, newsize, false) -} - -// freeStackSpans frees unused stack spans at the end of GC. -func freeStackSpans() { - lock(&stackpoolmu) - - // Scan stack pools for empty stack spans. - for order := range stackpool { - list := &stackpool[order] - for s := list.first; s != nil; { - next := s.next - if s.allocCount == 0 { - list.remove(s) - s.stackfreelist = 0 - mheap_.freeStack(s) - } - s = next - } - } - - unlock(&stackpoolmu) - - // Free large stack spans. - lock(&stackLarge.lock) - for i := range stackLarge.free { - for s := stackLarge.free[i].first; s != nil; { - next := s.next - stackLarge.free[i].remove(s) - mheap_.freeStack(s) - s = next - } - } - unlock(&stackLarge.lock) -} - -//go:nosplit -func morestackc() { - systemstack(func() { - throw("attempt to execute C code on Go stack") - }) -} -- cgit v1.1 From 746d6ed4ad8118e79eefa8f0d95c0ae5a9c4b9c0 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 2 May 2018 22:28:46 +0000 Subject: libgo: add support for the Nios II architecture Reviewed-on: https://go-review.googlesource.com/90775 From-SVN: r259866 --- libgo/configure | 7 +++++-- libgo/configure.ac | 7 +++++-- libgo/go/cmd/cgo/main.go | 2 ++ libgo/go/go/build/syslist.go | 2 +- libgo/go/internal/syscall/unix/getrandom_linux_generic.go | 2 +- libgo/go/runtime/hash32.go | 2 +- libgo/go/runtime/lfstack_32bit.go | 2 +- libgo/go/runtime/unaligned2.go | 2 +- libgo/go/syscall/endian_little.go | 2 +- libgo/go/syscall/libcall_linux_ustat.go | 2 +- libgo/goarch.sh | 7 +++++++ libgo/match.sh | 4 ++-- libgo/testsuite/gotest | 4 ++-- 13 files changed, 30 insertions(+), 15 deletions(-) (limited to 'libgo') diff --git a/libgo/configure b/libgo/configure index c5f8e8a..11e04aa 100755 --- a/libgo/configure +++ b/libgo/configure @@ -13653,10 +13653,10 @@ esac # - libgo/go/syscall/endian_XX.go # - possibly others # - possibly update files in libgo/go/internal/syscall/unix -ALLGOARCH="386 alpha amd64 amd64p32 arm armbe arm64 arm64be ia64 m68k mips mipsle mips64 mips64le mips64p32 mips64p32le ppc ppc64 ppc64le riscv64 s390 s390x sh shbe sparc sparc64" +ALLGOARCH="386 alpha amd64 amd64p32 arm armbe arm64 arm64be ia64 m68k mips mipsle mips64 mips64le mips64p32 mips64p32le nios2 ppc ppc64 ppc64le riscv64 s390 s390x sh shbe sparc sparc64" # All known GOARCH family values. -ALLGOARCHFAMILY="I386 ALPHA AMD64 ARM ARM64 IA64 M68K MIPS MIPS64 PPC PPC64 RISCV64 S390 S390X SH SPARC SPARC64" +ALLGOARCHFAMILY="I386 ALPHA AMD64 ARM ARM64 IA64 M68K MIPS MIPS64 NIOS2 PPC PPC64 RISCV64 S390 S390X SH SPARC SPARC64" GOARCH=unknown case ${host} in @@ -13745,6 +13745,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; esac ;; + nios2-*-*) + GOARCH=nios2 + ;; rs6000*-*-* | powerpc*-*-*) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ diff --git a/libgo/configure.ac b/libgo/configure.ac index eabe294..9f4bf50 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -224,10 +224,10 @@ AC_SUBST(USE_DEJAGNU) # - libgo/go/syscall/endian_XX.go # - possibly others # - possibly update files in libgo/go/internal/syscall/unix -ALLGOARCH="386 alpha amd64 amd64p32 arm armbe arm64 arm64be ia64 m68k mips mipsle mips64 mips64le mips64p32 mips64p32le ppc ppc64 ppc64le riscv64 s390 s390x sh shbe sparc sparc64" +ALLGOARCH="386 alpha amd64 amd64p32 arm armbe arm64 arm64be ia64 m68k mips mipsle mips64 mips64le mips64p32 mips64p32le nios2 ppc ppc64 ppc64le riscv64 s390 s390x sh shbe sparc sparc64" # All known GOARCH family values. -ALLGOARCHFAMILY="I386 ALPHA AMD64 ARM ARM64 IA64 M68K MIPS MIPS64 PPC PPC64 RISCV64 S390 S390X SH SPARC SPARC64" +ALLGOARCHFAMILY="I386 ALPHA AMD64 ARM ARM64 IA64 M68K MIPS MIPS64 NIOS2 PPC PPC64 RISCV64 S390 S390X SH SPARC SPARC64" GOARCH=unknown case ${host} in @@ -290,6 +290,9 @@ changequote([,])dnl ;; esac ;; + nios2-*-*) + GOARCH=nios2 + ;; rs6000*-*-* | powerpc*-*-*) AC_COMPILE_IFELSE([ #ifdef _ARCH_PPC64 diff --git a/libgo/go/cmd/cgo/main.go b/libgo/go/cmd/cgo/main.go index 6baabfd..890a365 100644 --- a/libgo/go/cmd/cgo/main.go +++ b/libgo/go/cmd/cgo/main.go @@ -165,6 +165,7 @@ var ptrSizeMap = map[string]int64{ "mips64le": 8, "mips64p32": 4, "mips64p32le": 4, + "nios2": 4, "ppc": 4, "ppc64": 8, "ppc64le": 8, @@ -190,6 +191,7 @@ var intSizeMap = map[string]int64{ "mips64le": 8, "mips64p32": 8, "mips64p32le": 8, + "nios2": 4, "ppc": 4, "ppc64": 8, "ppc64le": 8, diff --git a/libgo/go/go/build/syslist.go b/libgo/go/go/build/syslist.go index 679d195..0c39634 100644 --- a/libgo/go/go/build/syslist.go +++ b/libgo/go/go/build/syslist.go @@ -5,4 +5,4 @@ package build const goosList = "aix android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows zos " -const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be alpha m68k ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc riscv64 s390 s390x sh shbe sparc sparc64" +const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be alpha m68k ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le nios2 ppc riscv64 s390 s390x sh shbe sparc sparc64" diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_generic.go b/libgo/go/internal/syscall/unix/getrandom_linux_generic.go index d6af3de..2d513df 100644 --- a/libgo/go/internal/syscall/unix/getrandom_linux_generic.go +++ b/libgo/go/internal/syscall/unix/getrandom_linux_generic.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build arm64 riscv64 +// +build arm64 nios2 riscv64 package unix diff --git a/libgo/go/runtime/hash32.go b/libgo/go/runtime/hash32.go index 22daec5..3449127 100644 --- a/libgo/go/runtime/hash32.go +++ b/libgo/go/runtime/hash32.go @@ -6,7 +6,7 @@ // xxhash: https://code.google.com/p/xxhash/ // cityhash: https://code.google.com/p/cityhash/ -// +build 386 arm armbe m68k mips mipsle ppc s390 sh shbe sparc +// +build 386 arm armbe m68k mips mipsle nios2 ppc s390 sh shbe sparc package runtime diff --git a/libgo/go/runtime/lfstack_32bit.go b/libgo/go/runtime/lfstack_32bit.go index bbc421a..1288c1a 100644 --- a/libgo/go/runtime/lfstack_32bit.go +++ b/libgo/go/runtime/lfstack_32bit.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build 386 arm nacl armbe m68k mips mipsle mips64p32 mips64p32le ppc s390 sh shbe sparc +// +build 386 arm nacl armbe m68k mips mipsle mips64p32 mips64p32le nios2 ppc s390 sh shbe sparc package runtime diff --git a/libgo/go/runtime/unaligned2.go b/libgo/go/runtime/unaligned2.go index 891459e..9f52e8d 100644 --- a/libgo/go/runtime/unaligned2.go +++ b/libgo/go/runtime/unaligned2.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build arm mips mipsle mips64 mips64le armbe m68k sparc alpha ia64 mips64p32 mips64p32le sh shbe sparc64 +// +build alpha arm armbe ia64 m68k mips mipsle mips64 mips64le mips64p32 mips64p32le nios2 sh shbe sparc sparc64 package runtime diff --git a/libgo/go/syscall/endian_little.go b/libgo/go/syscall/endian_little.go index 4a73121..a5d32ae 100644 --- a/libgo/go/syscall/endian_little.go +++ b/libgo/go/syscall/endian_little.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // -// +build 386 amd64 amd64p32 arm arm64 ppc64le mips64le mipsle alpha ia64 mips64p32le sh riscv64 +// +build 386 alpha amd64 amd64p32 arm arm64 ia64 mips64le mipsle mips64p32le nios2 ppc64le riscv64 sh package syscall diff --git a/libgo/go/syscall/libcall_linux_ustat.go b/libgo/go/syscall/libcall_linux_ustat.go index 3aff344..f515fce 100644 --- a/libgo/go/syscall/libcall_linux_ustat.go +++ b/libgo/go/syscall/libcall_linux_ustat.go @@ -4,7 +4,7 @@ // GNU/Linux library ustat call. // This is not supported on some kernels, such as arm64. -// +build !arm64,!riscv64 +// +build !arm64,!nios2,!riscv64 package syscall diff --git a/libgo/goarch.sh b/libgo/goarch.sh index c63cbba..11bca7b 100755 --- a/libgo/goarch.sh +++ b/libgo/goarch.sh @@ -126,6 +126,13 @@ case $goarch in ;; esac ;; + nios2) + family=NIOS2 + cachelinesize=32 + minframesize=16 + pcquantum=4 + ptrsize=4 + ;; ppc) family=PPC bigendian=true diff --git a/libgo/match.sh b/libgo/match.sh index 9247ec6..fb80013 100755 --- a/libgo/match.sh +++ b/libgo/match.sh @@ -116,7 +116,7 @@ for f in $gofiles; do aix | android | darwin | dragonfly | freebsd | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag1=nonmatchingtag ;; - 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | ppc64 | ppc64le | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | ppc | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64) + 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64) tag1=nonmatchingtag ;; esac @@ -128,7 +128,7 @@ for f in $gofiles; do aix | android | darwin | dragonfly | freebsd | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag2=nonmatchingtag ;; - 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | ppc64 | ppc64le | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | ppc | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64) + 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64) tag2=nonmatchingtag ;; esac diff --git a/libgo/testsuite/gotest b/libgo/testsuite/gotest index 434c26d..d9353d1 100755 --- a/libgo/testsuite/gotest +++ b/libgo/testsuite/gotest @@ -314,7 +314,7 @@ x) aix | android | darwin | dragonfly | freebsd | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag1=nonmatchingtag ;; - 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | ppc64 | ppc64le | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | ppc | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64) + 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le·| nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64) tag1=nonmatchingtag ;; esac @@ -326,7 +326,7 @@ x) aix | android | darwin | dragonfly | freebsd | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag2=nonmatchingtag ;; - 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | ppc64 | ppc64le | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | ppc | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64) + 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le·| nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64) tag2=nonmatchingtag ;; esac -- cgit v1.1 From fbf2f198ce23f6859ccad3bf8b751cfa412da235 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 2 May 2018 22:32:23 +0000 Subject: libgo: add type/const references to sysinfo.c This patch adds explicit references to various types and constants defined by the header files included by sysinfo.c (used to drive the generation of gen-sysinfo.go as part of the libgo build via the GCC "-fdump-go-spec" option). The intent is to enable clients to gather the same info generated by "-fdump-go-spec" by instead reading the generated DWARF from a sysinfo.o object file compiled with "-g". Some compilers (notably clang) try to omit DWARF records for a given type unless there is an explicit use of it in the translation unit; the additional references are to insure that everything we want to see in the DWARF shows up. Reviewed-on: https://go-review.googlesource.com/99063 From-SVN: r259868 --- libgo/mksysinfo.sh | 1 + libgo/sysinfo.c | 209 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+) (limited to 'libgo') diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh index 1b40dbe..92ecb47 100755 --- a/libgo/mksysinfo.sh +++ b/libgo/mksysinfo.sh @@ -29,6 +29,7 @@ echo 'type _ unsafe.Pointer' >> ${OUT} # will all have a leading underscore. grep -v '^// ' gen-sysinfo.go | \ grep -v '^func' | \ + grep -v '^var' | \ grep -v '^type _timeval ' | \ grep -v '^type _timespec_t ' | \ grep -v '^type _timespec ' | \ diff --git a/libgo/sysinfo.c b/libgo/sysinfo.c index 884d017..fb11826 100644 --- a/libgo/sysinfo.c +++ b/libgo/sysinfo.c @@ -289,3 +289,212 @@ enum { epoll_data_offset = offsetof(struct epoll_event, data) }; #endif + +// The following section introduces explicit references to types and +// constants of interest to support bootstrapping libgo using a +// compiler that doesn't support -fdump-go-spec (e.g., clang), via +// DWARF-based tools. This process is made more difficult due to the +// fact that clang tries hard to omit types/constants from DWARF if it +// can't find explicit references to them, so here we make sure that +// key items are mentioned in ways that will force them into the +// generated DWARF. + +#if defined(__clang__) + +// Make a reference to a type +#define TREF(typ) typ typ ## ref + +// Make a reference to an opaque type +#define OTREF(typ) typ *typ ## ref + +// Make a reference to a struct tag +#define SREF(stag) struct stag stag ## ref + +// Make a reference to an enum literal +#define EREF(elit) unsigned elit ## fn(unsigned x) { return x == elit ? 1 : 0; } + +//...................................................................... + +// From dirent.h +SREF(dirent); +SREF(dirent64); +OTREF(DIR); + +// From fcntl.h +SREF(flock); +SREF(flock64); + +// From ffi headers +SREF(_ffi_type); +TREF(ffi_cif); +TREF(ffi_abi); +TREF(ffi_status); +EREF(FFI_OK); + +// From grp.h +SREF(group); + +#if defined(HAVE_LINUX_FILTER_H) +// From linux/filter.h +SREF(sock_filter); +SREF(sock_fprog); +#endif + +// From linux/if.h +EREF(IFF_UP); + +#if defined(HAVE_LINUX_IF_ADDR_H) +// From linux/if_addr.h +SREF(ifaddrmsg); +EREF(IFA_ADDRESS); +#endif + +#if defined(HAVE_LINUX_RTNETLINK_H) +// From linux/if_link.h +EREF(IFLA_ADDRESS); +#endif + +// From in.h, in6.h, icmp6.h +SREF(ip_mreq); +SREF(ip_mreqn); +SREF(ipv6_mreq); +SREF(ip6_mtuinfo); +SREF(icmp6_filter); +SREF(in_pktinfo); +EREF(IPPROTO_TCP); + +#if defined(HAVE_LINUX_RTNETLINK_H) +// From linux/rtnetlink.h +SREF(rtgenmsg); +SREF(rtmsg); +SREF(ifinfomsg); +SREF(rtattr); +SREF(rtnexthop); +EREF(RTM_BASE); +EREF(RTN_UNSPEC); +#endif + +// From netdb.h +SREF(addrinfo); + +// From netlink.h +SREF(nlattr); +SREF(nlmsgerr); + +// From pthread.h and related +TREF(pthread_attr_t); +TREF(pthread_t); +TREF(pthread_mutex_t); +TREF(pthread_mutexattr_t); + +// From pwd.h +SREF(passwd); + +// From signal.h and related +TREF(sigset_t); +TREF(siginfo_t); +TREF(stack_t); +SREF(sigaction); +SREF(sigstack); +EREF(SI_USER); +EREF(FPE_INTOVF); +EREF(BUS_ADRALN); +EREF(SS_ONSTACK); +EREF(SEGV_MAPERR); + +// From stat.h +SREF(stat64); + +// From statfs.h +SREF(statfs); +SREF(statfs64); + +// From sysinfo.h +SREF(sysinfo); + +// From +#if defined(HAVE_SYS_EPOLL_H) +SREF(epoll_event); +EREF(EPOLLIN); +EREF(epoll_data_offset); +#endif + +#if defined(HAVE_SYS_MOUNT_H) +// From sys/mount.h +EREF(MS_PRIVATE); +EREF(MNT_FORCE); +#endif + +#if defined(HAVE_SYS_PTRACE_H) +// From +SREF(pt_regs); +EREF(PTRACE_PEEKTEXT); +#endif + +// From sys/resource.h +SREF(rusage); +SREF(rlimit64); +EREF(RLIMIT_NOFILE); +EREF(PRIO_USER); + +// From sys/select.h +TREF(fd_set); + +// From sys/socket.h +SREF(msghdr); +SREF(cmsghdr); +SREF(ucred); +EREF(MSG_OOB); +EREF(SCM_RIGHTS); +EREF(SOCK_RAW); +EREF(SHUT_RD); + +// From sys/time.h and sys/times.h +SREF(timespec); +SREF(timeval); +SREF(itimerval); +SREF(tms); +EREF(ITIMER_PROF); + +#if defined(HAVE_SYS_TIMEX_H) +// From sys/timex.h +SREF(timex); +#endif + +// From sys/types.h +TREF(pid_t); +TREF(off_t); +TREF(loff_t); +TREF(size_t); +TREF(ssize_t); +TREF(mode_t); +TREF(dev_t); +TREF(time_t); + +// From sys/ucontext.h +TREF(ucontext_t); + +#if defined(HAVE_SYS_USER_H) +// From sys/user.h +SREF(user_regs_struct); +#endif + +#if defined(HAVE_SYS_UTSNAME_H) +// From sys/utsname.h +SREF(utsname); +#endif + +// From termios.h +SREF(termios); + +// From uio.h +SREF(iovec); + +// From utime.h +SREF(utimbuf); + +// From unistd.h +EREF(_PC_NAME_MAX); +EREF(_SC_GETPW_R_SIZE_MAX); + +#endif // clang -- cgit v1.1 From 5cf052826f45f14bdffbb3b59b66243dcb132a5b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 3 May 2018 03:19:28 +0000 Subject: cmd/go: run tests that require package build IDs These tests used to be disabled in the gofrontend since the go tool didn't support build IDs for the gofrontend. It does now, so enable the tests again. Reviewed-on: https://go-review.googlesource.com/111098 From-SVN: r259875 --- libgo/go/cmd/go/go_test.go | 2 -- 1 file changed, 2 deletions(-) (limited to 'libgo') diff --git a/libgo/go/cmd/go/go_test.go b/libgo/go/cmd/go/go_test.go index c5a3d7b..f522854 100644 --- a/libgo/go/cmd/go/go_test.go +++ b/libgo/go/cmd/go/go_test.go @@ -1034,7 +1034,6 @@ func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) { } func TestGoInstallDetectsRemovedFiles(t *testing.T) { - skipIfGccgo(t, "gccgo does not yet support package build IDs") tg := testgo(t) defer tg.cleanup() tg.parallel() @@ -1104,7 +1103,6 @@ func TestGoInstallErrorOnCrossCompileToBin(t *testing.T) { } func TestGoInstallDetectsRemovedFilesInPackageMain(t *testing.T) { - skipIfGccgo(t, "gccgo does not yet support package build IDs") tooSlow(t) tg := testgo(t) defer tg.cleanup() -- cgit v1.1 From 652293284321e34fa1d87ad70c28a854b5b47580 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 4 May 2018 01:34:30 +0000 Subject: cmd/go: update to match recent changes to gc In https://golang.org/cl/111097 the gc version of cmd/go was updated to include some gofrontend-specific changes. The gofrontend code already has different versions of those changes; this CL makes the gofrontend match the upstream code. Reviewed-on: https://go-review.googlesource.com/111099 From-SVN: r259918 --- libgo/go/cmd/go/alldocs.go | 6 +++--- libgo/go/cmd/go/internal/cfg/cfg.go | 11 +++++++---- libgo/go/cmd/go/internal/help/helpdoc.go | 6 +++--- libgo/go/cmd/go/internal/load/pkg.go | 3 +-- libgo/go/go/build/build.go | 9 +-------- libgo/go/go/build/gc.go | 17 +++++++++++++++++ libgo/go/go/build/gccgo.go | 14 ++++++++++++++ 7 files changed, 46 insertions(+), 20 deletions(-) create mode 100644 libgo/go/go/build/gc.go create mode 100644 libgo/go/go/build/gccgo.go (limited to 'libgo') diff --git a/libgo/go/cmd/go/alldocs.go b/libgo/go/cmd/go/alldocs.go index 5e1ac5a..aadf97c 100644 --- a/libgo/go/cmd/go/alldocs.go +++ b/libgo/go/cmd/go/alldocs.go @@ -1266,6 +1266,9 @@ // // Special-purpose environment variables: // +// GCCGOTOOLDIR +// If set, where to find gccgo tools, such as cgo. +// The default is based on how gccgo was configured. // GOROOT_FINAL // The root of the installed Go tree, when it is // installed in a location other than where it is built. @@ -1279,9 +1282,6 @@ // Defined by Git. A colon-separated list of schemes that are allowed to be used // with git fetch/clone. If set, any scheme not explicitly mentioned will be // considered insecure by 'go get'. -// GCCGOTOOLDIR -// If set, where to find gccgo tools, such as cgo. -// The default is based on how gccgo was configured. // // // Import path syntax diff --git a/libgo/go/cmd/go/internal/cfg/cfg.go b/libgo/go/cmd/go/internal/cfg/cfg.go index bfdd67e..f0a2277 100644 --- a/libgo/go/cmd/go/internal/cfg/cfg.go +++ b/libgo/go/cmd/go/internal/cfg/cfg.go @@ -92,11 +92,12 @@ var ( // Update build context to use our computed GOROOT. func init() { BuildContext.GOROOT = GOROOT - // Note that we must use runtime.GOOS and runtime.GOARCH here, - // as the tool directory does not move based on environment variables. - // This matches the initialization of ToolDir in go/build, - // except for using GOROOT rather than runtime.GOROOT(). if runtime.Compiler != "gccgo" { + // Note that we must use runtime.GOOS and runtime.GOARCH here, + // as the tool directory does not move based on environment + // variables. This matches the initialization of ToolDir in + // go/build, except for using GOROOT rather than + // runtime.GOROOT. build.ToolDir = filepath.Join(GOROOT, "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) } } @@ -107,6 +108,8 @@ func findGOROOT() string { } def := filepath.Clean(runtime.GOROOT()) if runtime.Compiler == "gccgo" { + // gccgo has no real GOROOT, and it certainly doesn't + // depend on the executable's location. return def } exe, err := os.Executable() diff --git a/libgo/go/cmd/go/internal/help/helpdoc.go b/libgo/go/cmd/go/internal/help/helpdoc.go index 9a9fc4e..6aa449a 100644 --- a/libgo/go/cmd/go/internal/help/helpdoc.go +++ b/libgo/go/cmd/go/internal/help/helpdoc.go @@ -526,6 +526,9 @@ Architecture-specific environment variables: Special-purpose environment variables: + GCCGOTOOLDIR + If set, where to find gccgo tools, such as cgo. + The default is based on how gccgo was configured. GOROOT_FINAL The root of the installed Go tree, when it is installed in a location other than where it is built. @@ -539,9 +542,6 @@ Special-purpose environment variables: Defined by Git. A colon-separated list of schemes that are allowed to be used with git fetch/clone. If set, any scheme not explicitly mentioned will be considered insecure by 'go get'. - GCCGOTOOLDIR - If set, where to find gccgo tools, such as cgo. - The default is based on how gccgo was configured. `, } diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go index 52ff6b8..d302607 100644 --- a/libgo/go/cmd/go/internal/load/pkg.go +++ b/libgo/go/cmd/go/internal/load/pkg.go @@ -13,7 +13,6 @@ import ( "os" pathpkg "path" "path/filepath" - "runtime" "sort" "strings" "unicode" @@ -976,7 +975,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { // This is for 'go tool'. // Override all the usual logic and force it into the tool directory. if cfg.BuildToolchainName == "gccgo" { - p.Target = filepath.Join(runtime.GCCGOTOOLDIR, elem) + p.Target = filepath.Join(base.ToolDir, elem) } else { p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full) } diff --git a/libgo/go/go/build/build.go b/libgo/go/go/build/build.go index 7902404..4e77955 100644 --- a/libgo/go/go/build/build.go +++ b/libgo/go/go/build/build.go @@ -1595,14 +1595,7 @@ func init() { } } -func getToolDir() string { - if runtime.Compiler == "gccgo" { - return envOr("GCCGOTOOLDIR", runtime.GCCGOTOOLDIR) - } else { - return filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) - } -} - +// ToolDir is the directory containing build tools. var ToolDir = getToolDir() // IsLocalImport reports whether the import path is diff --git a/libgo/go/go/build/gc.go b/libgo/go/go/build/gc.go new file mode 100644 index 0000000..3025cd5 --- /dev/null +++ b/libgo/go/go/build/gc.go @@ -0,0 +1,17 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build gc + +package build + +import ( + "path/filepath" + "runtime" +) + +// getToolDir returns the default value of ToolDir. +func getToolDir() string { + return filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) +} diff --git a/libgo/go/go/build/gccgo.go b/libgo/go/go/build/gccgo.go new file mode 100644 index 0000000..c6aac9a --- /dev/null +++ b/libgo/go/go/build/gccgo.go @@ -0,0 +1,14 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build gccgo + +package build + +import "runtime" + +// getToolDir returns the default value of ToolDir. +func getToolDir() string { + return envOr("GCCGOTOOLDIR", runtime.GCCGOTOOLDIR) +} -- cgit v1.1 From 28fc5502cffc8cc4bda8f61dbf8df90b21b5118d Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 4 May 2018 01:41:22 +0000 Subject: cmd/go: enable tests of vet tool Since gofrontend does have the vet tool now, we can test it. Reviewed-on: https://go-review.googlesource.com/111095 From-SVN: r259919 --- libgo/go/cmd/go/go_test.go | 4 ---- 1 file changed, 4 deletions(-) (limited to 'libgo') diff --git a/libgo/go/cmd/go/go_test.go b/libgo/go/cmd/go/go_test.go index f522854..2945418 100644 --- a/libgo/go/cmd/go/go_test.go +++ b/libgo/go/cmd/go/go_test.go @@ -3221,7 +3221,6 @@ func TestGoGetInternalWildcard(t *testing.T) { } func TestGoVetWithExternalTests(t *testing.T) { - skipIfGccgo(t, "gccgo does not have vet") tg := testgo(t) defer tg.cleanup() tg.makeTempdir() @@ -3231,7 +3230,6 @@ func TestGoVetWithExternalTests(t *testing.T) { } func TestGoVetWithTags(t *testing.T) { - skipIfGccgo(t, "gccgo does not have vet") tg := testgo(t) defer tg.cleanup() tg.makeTempdir() @@ -3241,7 +3239,6 @@ func TestGoVetWithTags(t *testing.T) { } func TestGoVetWithFlagsOn(t *testing.T) { - skipIfGccgo(t, "gccgo does not have vet") tg := testgo(t) defer tg.cleanup() tg.makeTempdir() @@ -3251,7 +3248,6 @@ func TestGoVetWithFlagsOn(t *testing.T) { } func TestGoVetWithFlagsOff(t *testing.T) { - skipIfGccgo(t, "gccgo does not have vet") tg := testgo(t) defer tg.cleanup() tg.makeTempdir() -- cgit v1.1 From 105073e1cc39fbeb03aa40e294ffc3c400cfa844 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 4 May 2018 01:43:39 +0000 Subject: cmd/go: update mkalldocs.sh Update mkalldocs.sh from the current master sources, replacing the old mkdoc.sh. Reviewed-on: https://go-review.googlesource.com/111096 From-SVN: r259920 --- libgo/go/cmd/go/mkalldocs.sh | 11 +++++++++++ libgo/go/cmd/go/mkdoc.sh | 9 --------- 2 files changed, 11 insertions(+), 9 deletions(-) create mode 100755 libgo/go/cmd/go/mkalldocs.sh delete mode 100644 libgo/go/cmd/go/mkdoc.sh (limited to 'libgo') diff --git a/libgo/go/cmd/go/mkalldocs.sh b/libgo/go/cmd/go/mkalldocs.sh new file mode 100755 index 0000000..72886db --- /dev/null +++ b/libgo/go/cmd/go/mkalldocs.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# Copyright 2012 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +set -e + +go build -o go.latest +./go.latest help documentation >alldocs.go +gofmt -w alldocs.go +rm go.latest diff --git a/libgo/go/cmd/go/mkdoc.sh b/libgo/go/cmd/go/mkdoc.sh deleted file mode 100644 index 12fd7ba..0000000 --- a/libgo/go/cmd/go/mkdoc.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -# Copyright 2012 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -go install # So the next line will produce updated documentation. -go help documentation > doc.go -gofmt -w doc.go - -- cgit v1.1 From 772455c964ec51d034ca32bb2718b239c01a05d2 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 4 May 2018 14:29:05 +0000 Subject: libgo: fix for unaligned read in go-unwind.c's read_encoded_value() Change code to work properly reading unaligned data on architectures that don't support unaliged reads. This fixes a regression (broke Solaris/sparc) introduced in https://golang.org/cl/90235. Reviewed-on: https://go-review.googlesource.com/111296 From-SVN: r259935 --- libgo/runtime/go-unwind.c | 54 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 11 deletions(-) (limited to 'libgo') diff --git a/libgo/runtime/go-unwind.c b/libgo/runtime/go-unwind.c index 536a619..a059acb 100644 --- a/libgo/runtime/go-unwind.c +++ b/libgo/runtime/go-unwind.c @@ -197,10 +197,6 @@ read_sleb128 (const uint8_t *p, _sleb128_t *val) #define ROUND_UP_TO_PVB(x) (x + sizeof(void *) - 1) &- sizeof(void *) -#define COPY_AND_ADVANCE(dst, ptr, typ) \ - (dst = *((const typ*)ptr), \ - ptr += sizeof(typ)) - static inline const uint8_t * read_encoded_value (struct _Unwind_Context *context, uint8_t encoding, const uint8_t *p, _Unwind_Ptr *val) @@ -221,17 +217,53 @@ read_encoded_value (struct _Unwind_Context *context, uint8_t encoding, switch (encoding & 0x0f) { case DW_EH_PE_sdata2: + { + int16_t result; + __builtin_memcpy (&result, p, sizeof(int16_t)); + decoded = result; + p += sizeof(int16_t); + break; + } case DW_EH_PE_udata2: - COPY_AND_ADVANCE (decoded, p, uint16_t); - break; + { + uint16_t result; + __builtin_memcpy (&result, p, sizeof(uint16_t)); + decoded = result; + p += sizeof(uint16_t); + break; + } case DW_EH_PE_sdata4: + { + int32_t result; + __builtin_memcpy (&result, p, sizeof(int32_t)); + decoded = result; + p += sizeof(int32_t); + break; + } case DW_EH_PE_udata4: - COPY_AND_ADVANCE (decoded, p, uint32_t); - break; + { + uint32_t result; + __builtin_memcpy (&result, p, sizeof(uint32_t)); + decoded = result; + p += sizeof(uint32_t); + break; + } case DW_EH_PE_sdata8: + { + int64_t result; + __builtin_memcpy (&result, p, sizeof(int64_t)); + decoded = result; + p += sizeof(int64_t); + break; + } case DW_EH_PE_udata8: - COPY_AND_ADVANCE (decoded, p, uint64_t); - break; + { + uint64_t result; + __builtin_memcpy (&result, p, sizeof(uint64_t)); + decoded = result; + p += sizeof(uint64_t); + break; + } case DW_EH_PE_uleb128: { _uleb128_t value; @@ -247,7 +279,7 @@ read_encoded_value (struct _Unwind_Context *context, uint8_t encoding, break; } case DW_EH_PE_absptr: - decoded = (_Unwind_Internal_Ptr)(*(const void *const *)p); + __builtin_memcpy (&decoded, (const void *)p, sizeof(const void*)); p += sizeof(void *); break; default: -- cgit v1.1 From 1c72513315c93a968acfdc5000b2f237480dbcba Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 4 May 2018 17:51:46 +0000 Subject: cmd/go: on AIX, pass -X64 first when invoking ar Reviewed-on: https://go-review.googlesource.com/111535 From-SVN: r259946 --- libgo/go/cmd/go/internal/work/gccgo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libgo') diff --git a/libgo/go/cmd/go/internal/work/gccgo.go b/libgo/go/cmd/go/internal/work/gccgo.go index 1ab7e4e..e8dab19 100644 --- a/libgo/go/cmd/go/internal/work/gccgo.go +++ b/libgo/go/cmd/go/internal/work/gccgo.go @@ -198,7 +198,7 @@ func (gccgoToolchain) pack(b *Builder, a *Action, afile string, ofiles []string) // AIX "ar" command does not know D option. arArgs = append(arArgs, "-X64") } - return b.run(a, p.Dir, p.ImportPath, nil, "ar", "rc", arArgs, absAfile, absOfiles) + return b.run(a, p.Dir, p.ImportPath, nil, "ar", arArgs, "rc", absAfile, absOfiles) } return nil } -- cgit v1.1 From 2f55f4aa6c403c58480cc9040b1c17238c17a54f Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 9 May 2018 21:49:47 +0000 Subject: go/build, cmd/go: update to match recent changes to gc Several recent changes to the gc version of cmd/go improve the gofrontend support. These changes are partially copies of existing gofrontend differences, and partially new code. This CL makes the gofrontend match the upstream code. The changes included here come from: https://golang.org/cl/111575 https://golang.org/cl/111595 https://golang.org/cl/111635 https://golang.org/cl/111636 For the record, the following recent gc changes are based on code already present in the gofrontend repo: https://golang.org/cl/110915 https://golang.org/cl/111615 For the record, a gc change, partially based on earlier gofrontend work, also with new gc code, was already copied to gofrontend repo in CL 111099: https://golang.org/cl/111097 This moves the generated list of standard library packages from cmd/go/internal/load to go/build. Reviewed-on: https://go-review.googlesource.com/112475 gotools/: * Makefile.am (check-go-tool): Don't copy zstdpkglist.go. * Makefile.in: Rebuild. From-SVN: r260097 --- libgo/Makefile.am | 10 +-- libgo/Makefile.in | 8 +-- libgo/go/cmd/go/internal/load/pkg.go | 19 ----- libgo/go/cmd/go/internal/test/test.go | 5 +- libgo/go/cmd/go/internal/work/buildid.go | 15 +--- libgo/go/cmd/go/internal/work/exec.go | 10 ++- libgo/go/go/build/build.go | 35 ++++++--- libgo/go/go/build/gc.go | 120 +++++++++++++++++++++++++++++++ libgo/go/go/build/gccgo.go | 6 ++ 9 files changed, 172 insertions(+), 56 deletions(-) (limited to 'libgo') diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 119d241..d847413 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -602,13 +602,13 @@ s-runtime-inc: runtime.lo Makefile $(SHELL) $(srcdir)/mvifdiff.sh tmp-runtime.inc runtime.inc $(STAMP) $@ -noinst_DATA += zstdpkglist.go zdefaultcc.go +noinst_DATA += zdefaultcc.go # Generate the list of go std packages that were included in libgo zstdpkglist.go: s-zstdpkglist; @true s-zstdpkglist: Makefile rm -f zstdpkglist.go.tmp - echo 'package load' > zstdpkglist.go.tmp + echo 'package build' > zstdpkglist.go.tmp echo "" >> zstdpkglist.go.tmp echo 'var stdpkg = map[string]bool{' >> zstdpkglist.go.tmp echo $(libgo_go_objs) 'unsafe.lo' 'runtime/cgo.lo' | sed 's|[a-z0-9_/]*_c\.lo||g' | sed 's|\([a-z0-9_/]*\)\.lo|"\1": true,|g' >> zstdpkglist.go.tmp @@ -960,6 +960,9 @@ runtime_pprof_check_GOCFLAGS = -static-libgo -fno-inline extra_go_files_runtime_internal_sys = version.go runtime/internal/sys.lo.dep: $(extra_go_files_runtime_internal_sys) +extra_go_files_go_build = zstdpkglist.go +go/build.lo.dep: $(extra_go_files_go_build) + extra_go_files_go_types = gccgosizes.go go/types.lo.dep: $(extra_go_files_go_types) @@ -969,9 +972,6 @@ cmd/internal/objabi.lo.dep: $(extra_go_files_cmd_internal_objabi) extra_go_files_cmd_go_internal_cfg = zdefaultcc.go cmd/go/internal/cfg.lo.dep: $(extra_go_files_cmd_go_internal_cfg) -extra_go_files_cmd_go_internal_load = zstdpkglist.go -cmd/go/internal/load.lo.dep: $(extra_go_files_cmd_go_internal_load) - extra_check_libs_cmd_go_internal_cache = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_generate = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_get = $(abs_builddir)/libgotool.a diff --git a/libgo/Makefile.in b/libgo/Makefile.in index a30e427..6b3c597 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -759,7 +759,7 @@ noinst_DATA = golang_org/x/net/internal/nettest.gox \ golang_org/x/net/nettest.gox internal/testenv.gox \ internal/trace.gox net/internal/socktest.gox \ os/signal/internal/pty.gox runtime/pprof/internal/profile.gox \ - zstdpkglist.go zdefaultcc.go + zdefaultcc.go @LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file = @LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c @LIBGO_IS_AIX_FALSE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_getncpu_file = runtime/getncpu-none.c @@ -999,10 +999,10 @@ runtime_internal_sys_lo_check_GOCFLAGS = -fgo-compiling-runtime # Also use -fno-inline to get better results from the memory profiler. runtime_pprof_check_GOCFLAGS = -static-libgo -fno-inline extra_go_files_runtime_internal_sys = version.go +extra_go_files_go_build = zstdpkglist.go extra_go_files_go_types = gccgosizes.go extra_go_files_cmd_internal_objabi = objabi.go extra_go_files_cmd_go_internal_cfg = zdefaultcc.go -extra_go_files_cmd_go_internal_load = zstdpkglist.go extra_check_libs_cmd_go_internal_cache = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_generate = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_get = $(abs_builddir)/libgotool.a @@ -2816,7 +2816,7 @@ s-runtime-inc: runtime.lo Makefile zstdpkglist.go: s-zstdpkglist; @true s-zstdpkglist: Makefile rm -f zstdpkglist.go.tmp - echo 'package load' > zstdpkglist.go.tmp + echo 'package build' > zstdpkglist.go.tmp echo "" >> zstdpkglist.go.tmp echo 'var stdpkg = map[string]bool{' >> zstdpkglist.go.tmp echo $(libgo_go_objs) 'unsafe.lo' 'runtime/cgo.lo' | sed 's|[a-z0-9_/]*_c\.lo||g' | sed 's|\([a-z0-9_/]*\)\.lo|"\1": true,|g' >> zstdpkglist.go.tmp @@ -2943,10 +2943,10 @@ $(foreach package,$(GOTOOL_PACKAGES),$(eval $(call PACKAGE_template,$(package))) runtime.lo.dep: $(extra_go_files_runtime) syscall.lo.dep: $(extra_go_files_syscall) runtime/internal/sys.lo.dep: $(extra_go_files_runtime_internal_sys) +go/build.lo.dep: $(extra_go_files_go_build) go/types.lo.dep: $(extra_go_files_go_types) cmd/internal/objabi.lo.dep: $(extra_go_files_cmd_internal_objabi) cmd/go/internal/cfg.lo.dep: $(extra_go_files_cmd_go_internal_cfg) -cmd/go/internal/load.lo.dep: $(extra_go_files_cmd_go_internal_load) # FIXME: The following C files may as well move to the runtime # directory and be treated like other C files. diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go index d302607..b2a757a 100644 --- a/libgo/go/cmd/go/internal/load/pkg.go +++ b/libgo/go/cmd/go/internal/load/pkg.go @@ -223,9 +223,6 @@ func (p *Package) copyBuild(pp *build.Package) { // TODO? Target p.Goroot = pp.Goroot p.Standard = p.Goroot && p.ImportPath != "" && isStandardImportPath(p.ImportPath) - if cfg.BuildToolchainName == "gccgo" { - p.Standard = stdpkg[p.ImportPath] - } p.GoFiles = pp.GoFiles p.CgoFiles = pp.CgoFiles p.IgnoredGoFiles = pp.IgnoredGoFiles @@ -894,13 +891,6 @@ var foldPath = make(map[string]string) func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { p.copyBuild(bp) - // When using gccgo the go/build package will not be able to - // find a standard package. It would be nicer to not get that - // error, but go/build doesn't know stdpkg. - if cfg.BuildToolchainName == "gccgo" && err != nil && p.Standard { - err = nil - } - // Decide whether p was listed on the command line. // Given that load is called while processing the command line, // you might think we could simply pass a flag down into load @@ -1096,9 +1086,6 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { continue } p1 := LoadImport(path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], UseVendor) - if cfg.BuildToolchainName == "gccgo" && p1.Standard { - continue - } if p.Standard && p.Error == nil && !p1.Standard && p1.Error == nil { p.Error = &PackageError{ ImportStack: stk.Copy(), @@ -1610,9 +1597,6 @@ func GetTestPackagesFor(p *Package, forceTest bool) (ptest, pxtest *Package, err rawTestImports := str.StringList(p.TestImports) for i, path := range p.TestImports { p1 := LoadImport(path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], UseVendor) - if cfg.BuildToolchainName == "gccgo" && p1.Standard { - continue - } if p1.Error != nil { return nil, nil, p1.Error } @@ -1641,9 +1625,6 @@ func GetTestPackagesFor(p *Package, forceTest bool) (ptest, pxtest *Package, err rawXTestImports := str.StringList(p.XTestImports) for i, path := range p.XTestImports { p1 := LoadImport(path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], UseVendor) - if cfg.BuildToolchainName == "gccgo" && p1.Standard { - continue - } if p1.Error != nil { return nil, nil, p1.Error } diff --git a/libgo/go/cmd/go/internal/test/test.go b/libgo/go/cmd/go/internal/test/test.go index 9785470..dbf6eea 100644 --- a/libgo/go/cmd/go/internal/test/test.go +++ b/libgo/go/cmd/go/internal/test/test.go @@ -633,6 +633,8 @@ func runTest(cmd *base.Command, args []string) { a := &work.Action{Mode: "go test -i"} for _, p := range load.PackagesForBuild(all) { if cfg.BuildToolchainName == "gccgo" && p.Standard { + // gccgo's standard library packages + // can not be reinstalled. continue } a.Deps = append(a.Deps, b.CompileAction(work.ModeInstall, work.ModeInstall, p)) @@ -862,9 +864,6 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin pmain.Internal.Imports = append(pmain.Internal.Imports, ptest) } else { p1 := load.LoadImport(dep, "", nil, &stk, nil, 0) - if cfg.BuildToolchainName == "gccgo" && p1.Standard { - continue - } if p1.Error != nil { return nil, nil, nil, p1.Error } diff --git a/libgo/go/cmd/go/internal/work/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go index 2636128..6150bbb 100644 --- a/libgo/go/cmd/go/internal/work/buildid.go +++ b/libgo/go/cmd/go/internal/work/buildid.go @@ -234,18 +234,9 @@ func (b *Builder) gccgoToolID(name, language string) (string, error) { // compile an empty file on standard input. cmdline := str.StringList(cfg.BuildToolexec, name, "-###", "-x", language, "-c", "-") cmd := exec.Command(cmdline[0], cmdline[1:]...) - - // Strip any LANG or LC_ environment variables, and force - // LANG=C, so that we get the untranslated output. - var env []string - for _, e := range os.Environ() { - if !strings.HasPrefix(e, "LANG=") && !strings.HasPrefix(e, "LC_") { - env = append(env, e) - } - } - env = append(env, "LANG=C") - - cmd.Env = base.EnvForDir(cmd.Dir, env) + cmd.Env = base.EnvForDir(cmd.Dir, os.Environ()) + // Force untranslated output so that we see the string "version". + cmd.Env = append(cmd.Env, "LC_ALL=C") out, err := cmd.CombinedOutput() if err != nil { return "", fmt.Errorf("%s: %v; output: %q", name, err, out) diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go index 40d4602..85bdff8 100644 --- a/libgo/go/cmd/go/internal/work/exec.go +++ b/libgo/go/cmd/go/internal/work/exec.go @@ -1545,6 +1545,8 @@ func joinUnambiguously(a []string) string { buf.WriteByte(' ') } q := strconv.Quote(s) + // A gccgo command line can contain -( and -). + // Make sure we quote them since they are special to the shell. if s == "" || strings.ContainsAny(s, " ()") || len(q) > len(s)+2 { buf.WriteString(q) } else { @@ -1585,13 +1587,17 @@ func (b *Builder) Mkdir(dir string) error { // symlink creates a symlink newname -> oldname. func (b *Builder) Symlink(oldname, newname string) error { + // It's not an error to try to recreate an existing symlink. + if link, err := os.Readlink(newname); err == nil && link == oldname { + return nil + } + if cfg.BuildN || cfg.BuildX { - b.Showcmd("", "ln -sf %s %s", oldname, newname) + b.Showcmd("", "ln -s %s %s", oldname, newname) if cfg.BuildN { return nil } } - os.Remove(newname) return os.Symlink(oldname, newname) } diff --git a/libgo/go/go/build/build.go b/libgo/go/go/build/build.go index 4e77955..9df4930 100644 --- a/libgo/go/go/build/build.go +++ b/libgo/go/go/build/build.go @@ -238,7 +238,7 @@ func (ctxt *Context) gopath() []string { // that do not exist. func (ctxt *Context) SrcDirs() []string { var all []string - if ctxt.GOROOT != "" { + if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" { dir := ctxt.joinPath(ctxt.GOROOT, "src") if ctxt.isDir(dir) { all = append(all, dir) @@ -540,7 +540,7 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa inTestdata := func(sub string) bool { return strings.Contains(sub, "/testdata/") || strings.HasSuffix(sub, "/testdata") || strings.HasPrefix(sub, "testdata/") || sub == "testdata" } - if ctxt.GOROOT != "" { + if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" { root := ctxt.joinPath(ctxt.GOROOT, "src") if sub, ok := ctxt.hasSubdir(root, p.Dir); ok && !inTestdata(sub) { p.Goroot = true @@ -557,7 +557,7 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa // We found a potential import path for dir, // but check that using it wouldn't find something // else first. - if ctxt.GOROOT != "" { + if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" { if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) { p.ConflictDir = dir goto Found @@ -622,7 +622,7 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa } return false } - if searchVendor(ctxt.GOROOT, true) { + if ctxt.Compiler != "gccgo" && searchVendor(ctxt.GOROOT, true) { goto Found } for _, root := range gopath { @@ -635,16 +635,24 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa // Determine directory from import path. if ctxt.GOROOT != "" { dir := ctxt.joinPath(ctxt.GOROOT, "src", path) - isDir := ctxt.isDir(dir) - binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga)) - if isDir || binaryOnly { - p.Dir = dir - p.Goroot = true - p.Root = ctxt.GOROOT - goto Found + if ctxt.Compiler != "gccgo" { + isDir := ctxt.isDir(dir) + binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga)) + if isDir || binaryOnly { + p.Dir = dir + p.Goroot = true + p.Root = ctxt.GOROOT + goto Found + } } tried.goroot = dir } + if ctxt.Compiler == "gccgo" && isStandardPackage(path) { + p.Dir = ctxt.joinPath(ctxt.GOROOT, "src", path) + p.Goroot = true + p.Root = ctxt.GOROOT + goto Found + } for _, root := range gopath { dir := ctxt.joinPath(root, "src", path) isDir := ctxt.isDir(dir) @@ -708,6 +716,11 @@ Found: return p, pkgerr } + if ctxt.Compiler == "gccgo" && p.Goroot { + // gccgo has no sources for GOROOT packages. + return p, nil + } + dirs, err := ctxt.readDir(p.Dir) if err != nil { return p, err diff --git a/libgo/go/go/build/gc.go b/libgo/go/go/build/gc.go index 3025cd5..e2be2cb 100644 --- a/libgo/go/go/build/gc.go +++ b/libgo/go/go/build/gc.go @@ -7,11 +7,131 @@ package build import ( + "os" + "os/exec" "path/filepath" "runtime" + "strings" + "sync" ) // getToolDir returns the default value of ToolDir. func getToolDir() string { return filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH) } + +// isStandardPackage is not used for the gc toolchain. +// However, this function may be called when using `go build -compiler=gccgo`. +func isStandardPackage(path string) bool { + return gccgoSearch.isStandard(path) +} + +// gccgoSearch holds the gccgo search directories. +type gccgoDirs struct { + once sync.Once + dirs []string +} + +// gccgoSearch is used to check whether a gccgo package exists in the +// standard library. +var gccgoSearch gccgoDirs + +// init finds the gccgo search directories. If this fails it leaves dirs == nil. +func (gd *gccgoDirs) init() { + gccgo := os.Getenv("GCCGO") + if gccgo == "" { + gccgo = "gccgo" + } + bin, err := exec.LookPath(gccgo) + if err != nil { + return + } + + allDirs, err := exec.Command(bin, "-print-search-dirs").Output() + if err != nil { + return + } + versionB, err := exec.Command(bin, "-dumpversion").Output() + if err != nil { + return + } + version := strings.TrimSpace(string(versionB)) + machineB, err := exec.Command(bin, "-dumpmachine").Output() + if err != nil { + return + } + machine := strings.TrimSpace(string(machineB)) + + dirsEntries := strings.Split(string(allDirs), "\n") + const prefix = "libraries: =" + var dirs []string + for _, dirEntry := range dirsEntries { + if strings.HasPrefix(dirEntry, prefix) { + dirs = filepath.SplitList(strings.TrimPrefix(dirEntry, prefix)) + break + } + } + if len(dirs) == 0 { + return + } + + var lastDirs []string + for _, dir := range dirs { + goDir := filepath.Join(dir, "go", version) + if fi, err := os.Stat(goDir); err == nil && fi.IsDir() { + gd.dirs = append(gd.dirs, goDir) + goDir = filepath.Join(goDir, machine) + if fi, err = os.Stat(goDir); err == nil && fi.IsDir() { + gd.dirs = append(gd.dirs, goDir) + } + } + if fi, err := os.Stat(dir); err == nil && fi.IsDir() { + lastDirs = append(lastDirs, dir) + } + } + gd.dirs = append(gd.dirs, lastDirs...) +} + +// isStandard returns whether path is a standard library for gccgo. +func (gd *gccgoDirs) isStandard(path string) bool { + // Quick check: if the first path component has a '.', it's not + // in the standard library. This skips most GOPATH directories. + i := strings.Index(path, "/") + if i < 0 { + i = len(path) + } + if strings.Contains(path[:i], ".") { + return false + } + + if path == "unsafe" { + // Special case. + return true + } + + gd.once.Do(gd.init) + if gd.dirs == nil { + // We couldn't find the gccgo search directories. + // Best guess, since the first component did not contain + // '.', is that this is a standard library package. + return true + } + + for _, dir := range gd.dirs { + full := filepath.Join(dir, path) + pkgdir, pkg := filepath.Split(full) + for _, p := range [...]string{ + full, + full + ".gox", + pkgdir + "lib" + pkg + ".so", + pkgdir + "lib" + pkg + ".a", + full + ".o", + } { + if fi, err := os.Stat(p); err == nil && !fi.IsDir() { + return true + } + } + } + + return false +} diff --git a/libgo/go/go/build/gccgo.go b/libgo/go/go/build/gccgo.go index c6aac9a..59e089d 100644 --- a/libgo/go/go/build/gccgo.go +++ b/libgo/go/go/build/gccgo.go @@ -12,3 +12,9 @@ import "runtime" func getToolDir() string { return envOr("GCCGOTOOLDIR", runtime.GCCGOTOOLDIR) } + +// isStandardPackage returns whether path names a standard library package. +// This uses a list generated at build time. +func isStandardPackage(path string) bool { + return stdpkg[path] +} -- cgit v1.1 From 4ec2cf3bd042a43eed1b46f80449893d149c1a7c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 30 May 2018 00:16:02 +0000 Subject: crypto/x509: specify path to AIX certificate file Reviewed-on: https://go-review.googlesource.com/113179 From-SVN: r260908 --- libgo/go/crypto/x509/root_aix.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'libgo') diff --git a/libgo/go/crypto/x509/root_aix.go b/libgo/go/crypto/x509/root_aix.go index de5702d..4e7e9dd 100644 --- a/libgo/go/crypto/x509/root_aix.go +++ b/libgo/go/crypto/x509/root_aix.go @@ -5,4 +5,6 @@ package x509 // Possible certificate files; stop after finding one. -var certFiles []string +var certFiles = []string{ + "/var/ssl/certs/ca-bundle.crt", +} -- cgit v1.1 From bb3976df48aecf734211898d6d954dc8ebed0713 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 30 May 2018 00:16:58 +0000 Subject: cmd/go, cmd/vet: make vet work with gccgo Backport https://golang.org/cl/113715 and https://golang.org/cl/113716: cmd/go: don't pass -compiler flag to vet Without this running go vet -compiler=gccgo causes vet to fail. The vet tool does need to know the compiler, but it is passed in vetConfig.Compiler. cmd/go, cmd/vet, go/internal/gccgoimport: make vet work with gccgo When using gccgo/GoLLVM, there is no package file for a standard library package. Since it is impossible for the go tool to rebuild the package, and since the package file exists only in the form of a .gox file, this seems like the best choice. Unfortunately it was confusing vet, which wanted to see a real file. This caused vet to report errors about missing package files for standard library packages. The gccgoimporter knows how to correctly handle this case. Fix this by 1) telling vet which packages are standard; 2) letting vet skip those packages; 3) letting the gccgoimporter handle this case. As a separate required fix, gccgo/GoLLVM has no runtime/cgo package, so don't try to depend on it (as it happens, this fixes golang/go#25324). The result is that the cmd/go vet tests pass when using -compiler=gccgo. Reviewed-on: https://go-review.googlesource.com/114516 From-SVN: r260913 --- libgo/go/cmd/go/internal/load/pkg.go | 8 +++++--- libgo/go/cmd/go/internal/vet/vetflag.go | 2 +- libgo/go/cmd/go/internal/work/exec.go | 20 ++++++++++++++++---- libgo/go/cmd/vet/main.go | 12 +++++++++++- libgo/go/go/internal/gccgoimporter/importer.go | 2 +- 5 files changed, 34 insertions(+), 10 deletions(-) (limited to 'libgo') diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go index b2a757a..882b86d 100644 --- a/libgo/go/cmd/go/internal/load/pkg.go +++ b/libgo/go/cmd/go/internal/load/pkg.go @@ -1010,7 +1010,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { // Cgo translation adds imports of "runtime/cgo" and "syscall", // except for certain packages, to avoid circular dependencies. - if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) { + if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" { addImport("runtime/cgo") } if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) { @@ -1019,7 +1019,9 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { // SWIG adds imports of some standard packages. if p.UsesSwig() { - addImport("runtime/cgo") + if cfg.BuildContext.Compiler != "gccgo" { + addImport("runtime/cgo") + } addImport("syscall") addImport("sync") @@ -1225,7 +1227,7 @@ func LinkerDeps(p *Package) []string { deps := []string{"runtime"} // External linking mode forces an import of runtime/cgo. - if externalLinkingForced(p) { + if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" { deps = append(deps, "runtime/cgo") } // On ARM with GOARM=5, it forces an import of math, for soft floating point. diff --git a/libgo/go/cmd/go/internal/vet/vetflag.go b/libgo/go/cmd/go/internal/vet/vetflag.go index d4664cc..03770ea 100644 --- a/libgo/go/cmd/go/internal/vet/vetflag.go +++ b/libgo/go/cmd/go/internal/vet/vetflag.go @@ -90,7 +90,7 @@ func vetFlags(args []string) (passToVet, packageNames []string) { } switch f.Name { // Flags known to the build but not to vet, so must be dropped. - case "x", "n", "vettool": + case "x", "n", "vettool", "compiler": if extraWord { args = append(args[:i], args[i+2:]...) extraWord = false diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go index 85bdff8..837ffb5 100644 --- a/libgo/go/cmd/go/internal/work/exec.go +++ b/libgo/go/cmd/go/internal/work/exec.go @@ -512,6 +512,7 @@ func (b *Builder) build(a *Action) (err error) { ImportPath: a.Package.ImportPath, ImportMap: make(map[string]string), PackageFile: make(map[string]string), + Standard: make(map[string]bool), } a.vetCfg = vcfg for i, raw := range a.Package.Internal.RawImports { @@ -548,17 +549,24 @@ func (b *Builder) build(a *Action) (err error) { for _, a1 := range a.Deps { p1 := a1.Package - if p1 == nil || p1.ImportPath == "" || a1.built == "" { + if p1 == nil || p1.ImportPath == "" { continue } - fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built) + if a1.built != "" { + fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built) + } if vcfg != nil { // Add import mapping if needed // (for imports like "runtime/cgo" that appear only in generated code). if !vcfgMapped[p1.ImportPath] { vcfg.ImportMap[p1.ImportPath] = p1.ImportPath } - vcfg.PackageFile[p1.ImportPath] = a1.built + if a1.built != "" { + vcfg.PackageFile[p1.ImportPath] = a1.built + } + if p1.Standard { + vcfg.Standard[p1.ImportPath] = true + } } } @@ -693,6 +701,7 @@ type vetConfig struct { GoFiles []string ImportMap map[string]string PackageFile map[string]string + Standard map[string]bool ImportPath string SucceedOnTypecheckFailure bool @@ -722,7 +731,10 @@ func (b *Builder) vet(a *Action) error { if vcfg.ImportMap["fmt"] == "" { a1 := a.Deps[1] vcfg.ImportMap["fmt"] = "fmt" - vcfg.PackageFile["fmt"] = a1.built + if a1.built != "" { + vcfg.PackageFile["fmt"] = a1.built + } + vcfg.Standard["fmt"] = true } // During go test, ignore type-checking failures during vet. diff --git a/libgo/go/cmd/vet/main.go b/libgo/go/cmd/vet/main.go index 9d28ebd..49c1d32 100644 --- a/libgo/go/cmd/vet/main.go +++ b/libgo/go/cmd/vet/main.go @@ -292,6 +292,7 @@ type vetConfig struct { GoFiles []string ImportMap map[string]string PackageFile map[string]string + Standard map[string]bool SucceedOnTypecheckFailure bool @@ -309,7 +310,12 @@ func (v *vetConfig) Import(path string) (*types.Package, error) { if p == "" { return nil, fmt.Errorf("unknown import path %q", path) } - if v.PackageFile[p] == "" && v.Compiler != "gccgo" { + if v.PackageFile[p] == "" { + if v.Compiler == "gccgo" && v.Standard[path] { + // gccgo doesn't have sources for standard library packages, + // but the importer will do the right thing. + return v.imp.Import(path) + } return nil, fmt.Errorf("unknown package file for import %q", path) } return v.imp.Import(p) @@ -318,6 +324,10 @@ func (v *vetConfig) Import(path string) (*types.Package, error) { func (v *vetConfig) openPackageFile(path string) (io.ReadCloser, error) { file := v.PackageFile[path] if file == "" { + if v.Compiler == "gccgo" && v.Standard[path] { + // The importer knows how to handle this. + return nil, nil + } // Note that path here has been translated via v.ImportMap, // unlike in the error in Import above. We prefer the error in // Import, but it's worth diagnosing this one too, just in case. diff --git a/libgo/go/go/internal/gccgoimporter/importer.go b/libgo/go/go/internal/gccgoimporter/importer.go index 843d196..ddaed40 100644 --- a/libgo/go/go/internal/gccgoimporter/importer.go +++ b/libgo/go/go/internal/gccgoimporter/importer.go @@ -176,7 +176,7 @@ func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Impo return p, nil } rc, err := lookup(pkgpath) - if err == nil { + if err == nil && rc != nil { defer rc.Close() rs, ok := rc.(io.ReadSeeker) if !ok { -- cgit v1.1 From 11309337c4056975c0fbd83a8caee7663617bef2 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 31 May 2018 21:42:53 +0000 Subject: libgo: update to Go 1.10.2 release Reviewed-on: https://go-review.googlesource.com/115196 From-SVN: r261041 --- libgo/MERGE | 2 +- libgo/VERSION | 2 +- libgo/check-packages.txt | 1 + libgo/go/archive/zip/reader.go | 8 +- libgo/go/archive/zip/reader_test.go | 2 +- libgo/go/cmd/go/go_test.go | 85 +++++++++++++ libgo/go/cmd/go/internal/get/vcs.go | 34 +++++- libgo/go/cmd/go/internal/get/vcs_test.go | 43 +++++++ libgo/go/cmd/go/internal/test/test.go | 8 ++ libgo/go/cmd/go/internal/vet/vet.go | 4 +- libgo/go/cmd/go/internal/work/buildid.go | 23 ++-- libgo/go/cmd/go/internal/work/exec.go | 18 ++- libgo/go/cmd/go/internal/work/security.go | 48 +++++++- libgo/go/cmd/go/internal/work/security_test.go | 4 - libgo/go/cmd/internal/objabi/funcid.go | 34 ++++++ libgo/go/crypto/x509/name_constraints_test.go | 135 ++++++++++++++++++++- libgo/go/crypto/x509/verify.go | 88 +++++++++++--- libgo/go/crypto/x509/x509.go | 20 ++- libgo/go/encoding/json/decode.go | 24 +++- libgo/go/encoding/json/decode_test.go | 70 ++++++++--- libgo/go/go/internal/srcimporter/srcimporter.go | 28 +---- .../go/go/internal/srcimporter/srcimporter_test.go | 32 +++++ .../srcimporter/testdata/issue23092/issue23092.go | 5 + .../srcimporter/testdata/issue24392/issue24392.go | 5 + libgo/go/internal/singleflight/singleflight.go | 22 +++- libgo/go/net/http/pprof/pprof.go | 52 ++++---- libgo/go/net/http/pprof/pprof_test.go | 69 +++++++++++ libgo/go/net/lookup.go | 32 +++-- libgo/go/net/lookup_test.go | 25 ++++ libgo/go/net/tcpsock_unix_test.go | 1 + libgo/go/runtime/error.go | 6 +- libgo/go/runtime/panic.go | 3 - libgo/go/runtime/proc.go | 6 + libgo/go/runtime/symtab.go | 29 +++++ libgo/misc/cgo/testplugin/src/issue24351/main.go | 21 ++++ libgo/misc/cgo/testplugin/src/issue24351/plugin.go | 14 +++ libgo/misc/cgo/testplugin/test.bash | 5 + libgo/misc/cgo/testshared/shared_test.go | 1 + 38 files changed, 852 insertions(+), 157 deletions(-) create mode 100644 libgo/go/cmd/internal/objabi/funcid.go create mode 100644 libgo/go/go/internal/srcimporter/testdata/issue23092/issue23092.go create mode 100644 libgo/go/go/internal/srcimporter/testdata/issue24392/issue24392.go create mode 100644 libgo/go/net/http/pprof/pprof_test.go create mode 100644 libgo/misc/cgo/testplugin/src/issue24351/main.go create mode 100644 libgo/misc/cgo/testplugin/src/issue24351/plugin.go (limited to 'libgo') diff --git a/libgo/MERGE b/libgo/MERGE index b715f06..6f31fab 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -bf86aec25972f3a100c3aa58a6abcbcc35bdea49 +71bdbf431b79dff61944f22c25c7e085ccfc25d5 The first line of this file holds the git revision number of the last merge done from the master library sources. diff --git a/libgo/VERSION b/libgo/VERSION index 95ec39e..98736c7 100644 --- a/libgo/VERSION +++ b/libgo/VERSION @@ -1 +1 @@ -go1.10 +go1.10.2 diff --git a/libgo/check-packages.txt b/libgo/check-packages.txt index 8ede851..82a08c6 100644 --- a/libgo/check-packages.txt +++ b/libgo/check-packages.txt @@ -122,6 +122,7 @@ net/http/httptest net/http/httptrace net/http/httputil net/http/internal +net/http/pprof net/internal/socktest net/mail net/rpc diff --git a/libgo/go/archive/zip/reader.go b/libgo/go/archive/zip/reader.go index 1563e74..2444106 100644 --- a/libgo/go/archive/zip/reader.go +++ b/libgo/go/archive/zip/reader.go @@ -366,7 +366,7 @@ parseExtras: epoch := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC) modified = time.Unix(epoch.Unix()+secs, nsecs) } - case unixExtraID: + case unixExtraID, infoZipUnixExtraID: if len(fieldBuf) < 8 { continue parseExtras } @@ -379,12 +379,6 @@ parseExtras: } ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch modified = time.Unix(ts, 0) - case infoZipUnixExtraID: - if len(fieldBuf) < 4 { - continue parseExtras - } - ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch - modified = time.Unix(ts, 0) } } diff --git a/libgo/go/archive/zip/reader_test.go b/libgo/go/archive/zip/reader_test.go index 0d9040f..1e58b26 100644 --- a/libgo/go/archive/zip/reader_test.go +++ b/libgo/go/archive/zip/reader_test.go @@ -414,7 +414,7 @@ var tests = []ZipTest{ Name: "test.txt", Content: []byte{}, Size: 1<<32 - 1, - Modified: time.Date(2017, 10, 31, 21, 17, 27, 0, timeZone(-7*time.Hour)), + Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)), Mode: 0644, }, }, diff --git a/libgo/go/cmd/go/go_test.go b/libgo/go/cmd/go/go_test.go index 2945418..f6d6f42 100644 --- a/libgo/go/cmd/go/go_test.go +++ b/libgo/go/cmd/go/go_test.go @@ -3265,6 +3265,20 @@ func TestGoVetWithOnlyTestFiles(t *testing.T) { tg.run("vet", "p") } +// Issue 24193. +func TestVetWithOnlyCgoFiles(t *testing.T) { + if !canCgo { + t.Skip("skipping because cgo not enabled") + } + + tg := testgo(t) + defer tg.cleanup() + tg.parallel() + tg.tempFile("src/p/p.go", "package p; import \"C\"; func F() {}") + tg.setenv("GOPATH", tg.path(".")) + tg.run("vet", "p") +} + // Issue 9767, 19769. func TestGoGetDotSlashDownload(t *testing.T) { testenv.MustHaveExternalNetwork(t) @@ -5099,6 +5113,28 @@ func TestCacheOutput(t *testing.T) { } } +func TestCacheListStale(t *testing.T) { + tooSlow(t) + if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") { + t.Skip("GODEBUG gocacheverify") + } + tg := testgo(t) + defer tg.cleanup() + tg.parallel() + tg.makeTempdir() + tg.setenv("GOCACHE", tg.path("cache")) + tg.tempFile("gopath/src/p/p.go", "package p; import _ \"q\"; func F(){}\n") + tg.tempFile("gopath/src/q/q.go", "package q; func F(){}\n") + tg.tempFile("gopath/src/m/m.go", "package main; import _ \"q\"; func main(){}\n") + + tg.setenv("GOPATH", tg.path("gopath")) + tg.run("install", "p", "m") + tg.run("list", "-f={{.ImportPath}} {{.Stale}}", "m", "q", "p") + tg.grepStdout("^m false", "m should not be stale") + tg.grepStdout("^q true", "q should be stale") + tg.grepStdout("^p false", "p should not be stale") +} + func TestCacheCoverage(t *testing.T) { tooSlow(t) @@ -5792,6 +5828,22 @@ func TestAtomicCoverpkgAll(t *testing.T) { } } +// Issue 23882. +func TestCoverpkgAllRuntime(t *testing.T) { + skipIfGccgo(t, "gccgo has no cover tool") + tg := testgo(t) + defer tg.cleanup() + tg.parallel() + + tg.tempFile("src/x/x.go", `package x; import _ "runtime"; func F() {}`) + tg.tempFile("src/x/x_test.go", `package x; import "testing"; func TestF(t *testing.T) { F() }`) + tg.setenv("GOPATH", tg.path(".")) + tg.run("test", "-coverpkg=all", "x") + if canRace { + tg.run("test", "-coverpkg=all", "-race", "x") + } +} + func TestBadCommandLines(t *testing.T) { tg := testgo(t) defer tg.cleanup() @@ -5949,3 +6001,36 @@ func TestBadCgoDirectives(t *testing.T) { tg.run("build", "-n", "x") tg.grepStderr("-D@foo", "did not find -D@foo in commands") } + +func TestTwoPkgConfigs(t *testing.T) { + if !canCgo { + t.Skip("no cgo") + } + if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { + t.Skipf("no shell scripts on %s", runtime.GOOS) + } + tg := testgo(t) + defer tg.cleanup() + tg.parallel() + tg.tempFile("src/x/a.go", `package x + // #cgo pkg-config: --static a + import "C" + `) + tg.tempFile("src/x/b.go", `package x + // #cgo pkg-config: --static a + import "C" + `) + tg.tempFile("pkg-config.sh", `#!/bin/sh +echo $* >>`+tg.path("pkg-config.out")) + tg.must(os.Chmod(tg.path("pkg-config.sh"), 0755)) + tg.setenv("GOPATH", tg.path(".")) + tg.setenv("PKG_CONFIG", tg.path("pkg-config.sh")) + tg.run("build", "x") + out, err := ioutil.ReadFile(tg.path("pkg-config.out")) + tg.must(err) + out = bytes.TrimSpace(out) + want := "--cflags --static --static -- a a\n--libs --static --static -- a a" + if !bytes.Equal(out, []byte(want)) { + t.Errorf("got %q want %q", out, want) + } +} diff --git a/libgo/go/cmd/go/internal/get/vcs.go b/libgo/go/cmd/go/internal/get/vcs.go index 26693b1..0b2a04e 100644 --- a/libgo/go/cmd/go/internal/get/vcs.go +++ b/libgo/go/cmd/go/internal/get/vcs.go @@ -809,8 +809,8 @@ func repoRootForImportDynamic(importPath string, security web.SecurityMode) (*re } } - if !strings.Contains(mmi.RepoRoot, "://") { - return nil, fmt.Errorf("%s: invalid repo root %q; no scheme", urlStr, mmi.RepoRoot) + if err := validateRepoRootScheme(mmi.RepoRoot); err != nil { + return nil, fmt.Errorf("%s: invalid repo root %q: %v", urlStr, mmi.RepoRoot, err) } rr := &repoRoot{ vcs: vcsByCmd(mmi.VCS), @@ -824,6 +824,36 @@ func repoRootForImportDynamic(importPath string, security web.SecurityMode) (*re return rr, nil } +// validateRepoRootScheme returns an error if repoRoot does not seem +// to have a valid URL scheme. At this point we permit things that +// aren't valid URLs, although later, if not using -insecure, we will +// restrict repoRoots to be valid URLs. This is only because we've +// historically permitted them, and people may depend on that. +func validateRepoRootScheme(repoRoot string) error { + end := strings.Index(repoRoot, "://") + if end <= 0 { + return errors.New("no scheme") + } + + // RFC 3986 section 3.1. + for i := 0; i < end; i++ { + c := repoRoot[i] + switch { + case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z': + // OK. + case '0' <= c && c <= '9' || c == '+' || c == '-' || c == '.': + // OK except at start. + if i == 0 { + return errors.New("invalid scheme") + } + default: + return errors.New("invalid scheme") + } + } + + return nil +} + var fetchGroup singleflight.Group var ( fetchCacheMu sync.Mutex diff --git a/libgo/go/cmd/go/internal/get/vcs_test.go b/libgo/go/cmd/go/internal/get/vcs_test.go index e29338a..a6f8642 100644 --- a/libgo/go/cmd/go/internal/get/vcs_test.go +++ b/libgo/go/cmd/go/internal/get/vcs_test.go @@ -408,3 +408,46 @@ func TestMatchGoImport(t *testing.T) { } } } + +func TestValidateRepoRootScheme(t *testing.T) { + tests := []struct { + root string + err string + }{ + { + root: "", + err: "no scheme", + }, + { + root: "http://", + err: "", + }, + { + root: "a://", + err: "", + }, + { + root: "a#://", + err: "invalid scheme", + }, + { + root: "-config://", + err: "invalid scheme", + }, + } + + for _, test := range tests { + err := validateRepoRootScheme(test.root) + if err == nil { + if test.err != "" { + t.Errorf("validateRepoRootScheme(%q) = nil, want %q", test.root, test.err) + } + } else if test.err == "" { + if err != nil { + t.Errorf("validateRepoRootScheme(%q) = %q, want nil", test.root, test.err) + } + } else if err.Error() != test.err { + t.Errorf("validateRepoRootScheme(%q) = %q, want %q", test.root, err, test.err) + } + } +} diff --git a/libgo/go/cmd/go/internal/test/test.go b/libgo/go/cmd/go/internal/test/test.go index dbf6eea..72415cc 100644 --- a/libgo/go/cmd/go/internal/test/test.go +++ b/libgo/go/cmd/go/internal/test/test.go @@ -673,6 +673,14 @@ func runTest(cmd *base.Command, args []string) { continue } + // If using the race detector, silently ignore + // attempts to run coverage on the runtime + // packages. It will cause the race detector + // to be invoked before it has been initialized. + if cfg.BuildRace && p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) { + continue + } + if haveMatch { testCoverPkgs = append(testCoverPkgs, p) } diff --git a/libgo/go/cmd/go/internal/vet/vet.go b/libgo/go/cmd/go/internal/vet/vet.go index 07eed89..a737ebd 100644 --- a/libgo/go/cmd/go/internal/vet/vet.go +++ b/libgo/go/cmd/go/internal/vet/vet.go @@ -62,11 +62,11 @@ func runVet(cmd *base.Command, args []string) { base.Errorf("%v", err) continue } - if len(ptest.GoFiles) == 0 && pxtest == nil { + if len(ptest.GoFiles) == 0 && len(ptest.CgoFiles) == 0 && pxtest == nil { base.Errorf("go vet %s: no Go files in %s", p.ImportPath, p.Dir) continue } - if len(ptest.GoFiles) > 0 { + if len(ptest.GoFiles) > 0 || len(ptest.CgoFiles) > 0 { root.Deps = append(root.Deps, b.VetAction(work.ModeBuild, work.ModeBuild, ptest)) } if pxtest != nil { diff --git a/libgo/go/cmd/go/internal/work/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go index 6150bbb..733938e 100644 --- a/libgo/go/cmd/go/internal/work/buildid.go +++ b/libgo/go/cmd/go/internal/work/buildid.go @@ -461,15 +461,7 @@ func (b *Builder) useCache(a *Action, p *load.Package, actionHash cache.ActionID // If so, it's up to date and we can reuse it instead of rebuilding it. var buildID string if target != "" && !cfg.BuildA { - var err error - buildID, err = buildid.ReadFile(target) - if err != nil && b.ComputeStaleOnly { - if p != nil && !p.Stale { - p.Stale = true - p.StaleReason = "target missing" - } - return true - } + buildID, _ = buildid.ReadFile(target) if strings.HasPrefix(buildID, actionID+buildIDSeparator) { a.buildID = buildID a.built = target @@ -546,7 +538,10 @@ func (b *Builder) useCache(a *Action, p *load.Package, actionHash cache.ActionID } } } - return true + + // Fall through to update a.buildID from the build artifact cache, + // which will affect the computation of buildIDs for targets + // higher up in the dependency graph. } // Check the build artifact cache. @@ -574,6 +569,10 @@ func (b *Builder) useCache(a *Action, p *load.Package, actionHash cache.ActionID a.built = file a.Target = "DO NOT USE - using cache" a.buildID = buildID + if p := a.Package; p != nil { + // Clearer than explaining that something else is stale. + p.StaleReason = "not installed but available in build cache" + } return true } } @@ -584,6 +583,10 @@ func (b *Builder) useCache(a *Action, p *load.Package, actionHash cache.ActionID a.output = []byte{} } + if b.ComputeStaleOnly { + return true + } + return false } diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go index 837ffb5..5994dbc 100644 --- a/libgo/go/cmd/go/internal/work/exec.go +++ b/libgo/go/cmd/go/internal/work/exec.go @@ -956,11 +956,19 @@ func splitPkgConfigOutput(out []byte) []string { // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package. func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, err error) { - if pkgs := p.CgoPkgConfig; len(pkgs) > 0 { + if pcargs := p.CgoPkgConfig; len(pcargs) > 0 { + // pkg-config permits arguments to appear anywhere in + // the command line. Move them all to the front, before --. var pcflags []string - for len(pkgs) > 0 && strings.HasPrefix(pkgs[0], "--") { - pcflags = append(pcflags, pkgs[0]) - pkgs = pkgs[1:] + var pkgs []string + for _, pcarg := range pcargs { + if pcarg == "--" { + // We're going to add our own "--" argument. + } else if strings.HasPrefix(pcarg, "--") { + pcflags = append(pcflags, pcarg) + } else { + pkgs = append(pkgs, pcarg) + } } for _, pkg := range pkgs { if !load.SafeArg(pkg) { @@ -1107,7 +1115,7 @@ func BuildInstallFunc(b *Builder, a *Action) (err error) { // We want to hide that awful detail as much as possible, so don't // advertise it by touching the mtimes (usually the libraries are up // to date). - if !a.buggyInstall { + if !a.buggyInstall && !b.ComputeStaleOnly { now := time.Now() os.Chtimes(a.Target, now, now) } diff --git a/libgo/go/cmd/go/internal/work/security.go b/libgo/go/cmd/go/internal/work/security.go index 54fd6b9..5c67aa9 100644 --- a/libgo/go/cmd/go/internal/work/security.go +++ b/libgo/go/cmd/go/internal/work/security.go @@ -46,12 +46,19 @@ var validCompilerFlags = []*regexp.Regexp{ re(`-O([^@\-].*)`), re(`-W`), re(`-W([^@,]+)`), // -Wall but not -Wa,-foo. + re(`-Wa,-mbig-obj`), + re(`-ansi`), re(`-f(no-)?blocks`), re(`-f(no-)?common`), re(`-f(no-)?constant-cfstrings`), + re(`-fdiagnostics-show-note-include-stack`), re(`-f(no-)?exceptions`), + re(`-f(no-)?inline-functions`), re(`-finput-charset=([^@\-].*)`), + re(`-f(no-)?fat-lto-objects`), re(`-f(no-)?lto`), + re(`-fmacro-backtrace-limit=(.+)`), + re(`-fmessage-length=(.+)`), re(`-f(no-)?modules`), re(`-f(no-)?objc-arc`), re(`-f(no-)?omit-frame-pointer`), @@ -62,27 +69,42 @@ var validCompilerFlags = []*regexp.Regexp{ re(`-f(no-)?split-stack`), re(`-f(no-)?stack-(.+)`), re(`-f(no-)?strict-aliasing`), + re(`-f(un)signed-char`), + re(`-f(no-)?use-linker-plugin`), // safe if -B is not used; we don't permit -B re(`-fsanitize=(.+)`), + re(`-ftemplate-depth-(.+)`), + re(`-fvisibility=(.+)`), re(`-g([^@\-].*)?`), + re(`-m32`), + re(`-m64`), re(`-m(arch|cpu|fpu|tune)=([^@\-].*)`), re(`-m(no-)?avx[0-9a-z.]*`), re(`-m(no-)?ms-bitfields`), re(`-m(no-)?stack-(.+)`), re(`-mmacosx-(.+)`), + re(`-mios-simulator-version-min=(.+)`), + re(`-miphoneos-version-min=(.+)`), re(`-mnop-fun-dllimport`), re(`-m(no-)?sse[0-9.]*`), + re(`-mwindows`), re(`-pedantic(-errors)?`), re(`-pipe`), re(`-pthread`), re(`-?-std=([^@\-].*)`), + re(`-?-stdlib=([^@\-].*)`), + re(`-w`), re(`-x([^@\-].*)`), } var validCompilerFlagsWithNextArg = []string{ + "-arch", "-D", "-I", - "-isystem", "-framework", + "-isysroot", + "-isystem", + "--sysroot", + "-target", "-x", } @@ -90,43 +112,65 @@ var validLinkerFlags = []*regexp.Regexp{ re(`-F([^@\-].*)`), re(`-l([^@\-].*)`), re(`-L([^@\-].*)`), + re(`-O`), + re(`-O([^@\-].*)`), re(`-f(no-)?(pic|PIC|pie|PIE)`), re(`-fsanitize=([^@\-].*)`), re(`-g([^@\-].*)?`), re(`-m(arch|cpu|fpu|tune)=([^@\-].*)`), + re(`-mmacosx-(.+)`), + re(`-mios-simulator-version-min=(.+)`), + re(`-miphoneos-version-min=(.+)`), + re(`-mwindows`), re(`-(pic|PIC|pie|PIE)`), re(`-pthread`), + re(`-shared`), re(`-?-static([-a-z0-9+]*)`), + re(`-?-stdlib=([^@\-].*)`), // Note that any wildcards in -Wl need to exclude comma, // since -Wl splits its argument at commas and passes // them all to the linker uninterpreted. Allowing comma // in a wildcard would allow tunnelling arbitrary additional // linker arguments through one of these. + re(`-Wl,--(no-)?allow-multiple-definition`), re(`-Wl,--(no-)?as-needed`), re(`-Wl,-Bdynamic`), re(`-Wl,-Bstatic`), + re(`-Wl,-d[ny]`), re(`-Wl,--disable-new-dtags`), re(`-Wl,--enable-new-dtags`), re(`-Wl,--end-group`), re(`-Wl,-framework,[^,@\-][^,]+`), re(`-Wl,-headerpad_max_install_names`), re(`-Wl,--no-undefined`), - re(`-Wl,-rpath,([^,@\-][^,]+)`), + re(`-Wl,-rpath[=,]([^,@\-][^,]+)`), re(`-Wl,-search_paths_first`), + re(`-Wl,-sectcreate,([^,@\-][^,]+),([^,@\-][^,]+),([^,@\-][^,]+)`), re(`-Wl,--start-group`), + re(`-Wl,-?-static`), + re(`-Wl,--subsystem,(native|windows|console|posix|xbox)`), + re(`-Wl,-undefined[=,]([^,@\-][^,]+)`), re(`-Wl,-?-unresolved-symbols=[^,]+`), re(`-Wl,--(no-)?warn-([^,]+)`), + re(`-Wl,-z,(no)?execstack`), + re(`-Wl,-z,relro`), re(`[a-zA-Z0-9_/].*\.(a|o|obj|dll|dylib|so)`), // direct linker inputs: x.o or libfoo.so (but not -foo.o or @foo.o) } var validLinkerFlagsWithNextArg = []string{ + "-arch", "-F", "-l", "-L", "-framework", + "-isysroot", + "--sysroot", + "-target", "-Wl,-framework", + "-Wl,-rpath", + "-Wl,-undefined", } func checkCompilerFlags(name, source string, list []string) error { diff --git a/libgo/go/cmd/go/internal/work/security_test.go b/libgo/go/cmd/go/internal/work/security_test.go index 976501b..bd898c9 100644 --- a/libgo/go/cmd/go/internal/work/security_test.go +++ b/libgo/go/cmd/go/internal/work/security_test.go @@ -140,9 +140,6 @@ var goodLinkerFlags = [][]string{ var badLinkerFlags = [][]string{ {"-DFOO"}, {"-Dfoo=bar"}, - {"-O"}, - {"-O2"}, - {"-Osmall"}, {"-W"}, {"-Wall"}, {"-fobjc-arc"}, @@ -155,7 +152,6 @@ var badLinkerFlags = [][]string{ {"-fno-stack-xxx"}, {"-mstack-overflow"}, {"-mno-stack-overflow"}, - {"-mmacosx-version"}, {"-mnop-fun-dllimport"}, {"-std=c99"}, {"-xc"}, diff --git a/libgo/go/cmd/internal/objabi/funcid.go b/libgo/go/cmd/internal/objabi/funcid.go new file mode 100644 index 0000000..55f1328 --- /dev/null +++ b/libgo/go/cmd/internal/objabi/funcid.go @@ -0,0 +1,34 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package objabi + +// A FuncID identifies particular functions that need to be treated +// specially by the runtime. +// Note that in some situations involving plugins, there may be multiple +// copies of a particular special runtime function. +// Note: this list must match the list in runtime/symtab.go. +type FuncID uint32 + +const ( + FuncID_normal FuncID = iota // not a special function + FuncID_goexit + FuncID_jmpdefer + FuncID_mcall + FuncID_morestack + FuncID_mstart + FuncID_rt0_go + FuncID_asmcgocall + FuncID_sigpanic + FuncID_runfinq + FuncID_bgsweep + FuncID_forcegchelper + FuncID_timerproc + FuncID_gcBgMarkWorker + FuncID_systemstack_switch + FuncID_systemstack + FuncID_cgocallback_gofunc + FuncID_gogo + FuncID_externalthreadhandler +) diff --git a/libgo/go/crypto/x509/name_constraints_test.go b/libgo/go/crypto/x509/name_constraints_test.go index 10cc348..bad488f 100644 --- a/libgo/go/crypto/x509/name_constraints_test.go +++ b/libgo/go/crypto/x509/name_constraints_test.go @@ -11,6 +11,7 @@ import ( "crypto/rand" "crypto/x509/pkix" "encoding/asn1" + "encoding/hex" "encoding/pem" "fmt" "io/ioutil" @@ -42,6 +43,7 @@ type nameConstraintsTest struct { roots []constraintsSpec intermediates [][]constraintsSpec leaf leafSpec + requestedEKUs []ExtKeyUsage expectedError string noOpenSSL bool } @@ -1444,6 +1446,118 @@ var nameConstraintsTests = []nameConstraintsTest{ }, expectedError: "\"https://example.com/test\" is excluded", }, + + // #75: While serverAuth in a CA certificate permits clientAuth in a leaf, + // serverAuth in a leaf shouldn't permit clientAuth when requested in + // VerifyOptions. + nameConstraintsTest{ + roots: []constraintsSpec{ + constraintsSpec{}, + }, + intermediates: [][]constraintsSpec{ + []constraintsSpec{ + constraintsSpec{}, + }, + }, + leaf: leafSpec{ + sans: []string{"dns:example.com"}, + ekus: []string{"serverAuth"}, + }, + requestedEKUs: []ExtKeyUsage{ExtKeyUsageClientAuth}, + expectedError: "incompatible key usage", + }, + + // #76: However, MSSGC in a leaf should match a request for serverAuth. + nameConstraintsTest{ + roots: []constraintsSpec{ + constraintsSpec{}, + }, + intermediates: [][]constraintsSpec{ + []constraintsSpec{ + constraintsSpec{}, + }, + }, + leaf: leafSpec{ + sans: []string{"dns:example.com"}, + ekus: []string{"msSGC"}, + }, + requestedEKUs: []ExtKeyUsage{ExtKeyUsageServerAuth}, + }, + + // An invalid DNS SAN should be detected only at validation time so + // that we can process CA certificates in the wild that have invalid SANs. + // See https://github.com/golang/go/issues/23995 + + // #77: an invalid DNS or mail SAN will not be detected if name constaint + // checking is not triggered. + nameConstraintsTest{ + roots: []constraintsSpec{ + constraintsSpec{}, + }, + intermediates: [][]constraintsSpec{ + []constraintsSpec{ + constraintsSpec{}, + }, + }, + leaf: leafSpec{ + sans: []string{"dns:this is invalid", "email:this @ is invalid"}, + }, + }, + + // #78: an invalid DNS SAN will be detected if any name constraint checking + // is triggered. + nameConstraintsTest{ + roots: []constraintsSpec{ + constraintsSpec{ + bad: []string{"uri:"}, + }, + }, + intermediates: [][]constraintsSpec{ + []constraintsSpec{ + constraintsSpec{}, + }, + }, + leaf: leafSpec{ + sans: []string{"dns:this is invalid"}, + }, + expectedError: "cannot parse dnsName", + }, + + // #79: an invalid email SAN will be detected if any name constraint + // checking is triggered. + nameConstraintsTest{ + roots: []constraintsSpec{ + constraintsSpec{ + bad: []string{"uri:"}, + }, + }, + intermediates: [][]constraintsSpec{ + []constraintsSpec{ + constraintsSpec{}, + }, + }, + leaf: leafSpec{ + sans: []string{"email:this @ is invalid"}, + }, + expectedError: "cannot parse rfc822Name", + }, + + // #80: if several EKUs are requested, satisfying any of them is sufficient. + nameConstraintsTest{ + roots: []constraintsSpec{ + constraintsSpec{}, + }, + intermediates: [][]constraintsSpec{ + []constraintsSpec{ + constraintsSpec{}, + }, + }, + leaf: leafSpec{ + sans: []string{"dns:example.com"}, + ekus: []string{"email"}, + }, + requestedEKUs: []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageEmailProtection}, + }, } func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) { @@ -1459,7 +1573,7 @@ func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa. NotAfter: time.Unix(2000, 0), KeyUsage: KeyUsageCertSign, BasicConstraintsValid: true, - IsCA: true, + IsCA: true, } if err := addConstraintsToTemplate(constraints, template); err != nil { @@ -1497,7 +1611,7 @@ func makeConstraintsLeafCert(leaf leafSpec, key *ecdsa.PrivateKey, parent *Certi NotAfter: time.Unix(2000, 0), KeyUsage: KeyUsageDigitalSignature, BasicConstraintsValid: true, - IsCA: false, + IsCA: false, } for _, name := range leaf.sans { @@ -1512,6 +1626,13 @@ func makeConstraintsLeafCert(leaf leafSpec, key *ecdsa.PrivateKey, parent *Certi } template.IPAddresses = append(template.IPAddresses, ip) + case strings.HasPrefix(name, "invalidip:"): + ipBytes, err := hex.DecodeString(name[10:]) + if err != nil { + return nil, fmt.Errorf("cannot parse invalid IP: %s", err) + } + template.IPAddresses = append(template.IPAddresses, net.IP(ipBytes)) + case strings.HasPrefix(name, "email:"): template.EmailAddresses = append(template.EmailAddresses, name[6:]) @@ -1781,6 +1902,7 @@ func TestConstraintCases(t *testing.T) { Roots: rootPool, Intermediates: intermediatePool, CurrentTime: time.Unix(1500, 0), + KeyUsages: test.requestedEKUs, } _, err = leafCert.Verify(verifyOpts) @@ -1972,12 +2094,13 @@ func TestBadNamesInConstraints(t *testing.T) { } func TestBadNamesInSANs(t *testing.T) { - // Bad names in SANs should not parse. + // Bad names in URI and IP SANs should not parse. Bad DNS and email SANs + // will parse and are tested in name constraint tests at the top of this + // file. badNames := []string{ - "dns:foo.com.", - "email:abc@foo.com.", - "email:foo.com.", "uri:https://example.com./dsf", + "invalidip:0102", + "invalidip:0102030405", } priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) diff --git a/libgo/go/crypto/x509/verify.go b/libgo/go/crypto/x509/verify.go index 9477e85..0ea214b 100644 --- a/libgo/go/crypto/x509/verify.go +++ b/libgo/go/crypto/x509/verify.go @@ -6,12 +6,14 @@ package x509 import ( "bytes" + "encoding/asn1" "errors" "fmt" "net" "net/url" "reflect" "runtime" + "strconv" "strings" "time" "unicode/utf8" @@ -178,10 +180,14 @@ type VerifyOptions struct { Intermediates *CertPool Roots *CertPool // if nil, the system roots are used CurrentTime time.Time // if zero, the current time is used - // KeyUsage specifies which Extended Key Usage values are acceptable. - // An empty list means ExtKeyUsageServerAuth. Key usage is considered a - // constraint down the chain which mirrors Windows CryptoAPI behavior, - // but not the spec. To accept any key usage, include ExtKeyUsageAny. + // KeyUsage specifies which Extended Key Usage values are acceptable. A leaf + // certificate is accepted if it contains any of the listed values. An empty + // list means ExtKeyUsageServerAuth. To accept any key usage, include + // ExtKeyUsageAny. + // + // Certificate chains are required to nest extended key usage values, + // irrespective of this value. This matches the Windows CryptoAPI behavior, + // but not the spec. KeyUsages []ExtKeyUsage // MaxConstraintComparisions is the maximum number of comparisons to // perform when checking a given certificate's name constraints. If @@ -543,11 +549,16 @@ func (c *Certificate) checkNameConstraints(count *int, return nil } +const ( + checkingAgainstIssuerCert = iota + checkingAgainstLeafCert +) + // ekuPermittedBy returns true iff the given extended key usage is permitted by // the given EKU from a certificate. Normally, this would be a simple // comparison plus a special case for the “any” EKU. But, in order to support // existing certificates, some exceptions are made. -func ekuPermittedBy(eku, certEKU ExtKeyUsage) bool { +func ekuPermittedBy(eku, certEKU ExtKeyUsage, context int) bool { if certEKU == ExtKeyUsageAny || eku == certEKU { return true } @@ -564,18 +575,23 @@ func ekuPermittedBy(eku, certEKU ExtKeyUsage) bool { eku = mapServerAuthEKUs(eku) certEKU = mapServerAuthEKUs(certEKU) - if eku == certEKU || - // ServerAuth in a CA permits ClientAuth in the leaf. - (eku == ExtKeyUsageClientAuth && certEKU == ExtKeyUsageServerAuth) || + if eku == certEKU { + return true + } + + // If checking a requested EKU against the list in a leaf certificate there + // are fewer exceptions. + if context == checkingAgainstLeafCert { + return false + } + + // ServerAuth in a CA permits ClientAuth in the leaf. + return (eku == ExtKeyUsageClientAuth && certEKU == ExtKeyUsageServerAuth) || // Any CA may issue an OCSP responder certificate. eku == ExtKeyUsageOCSPSigning || // Code-signing CAs can use Microsoft's commercial and // kernel-mode EKUs. - ((eku == ExtKeyUsageMicrosoftCommercialCodeSigning || eku == ExtKeyUsageMicrosoftKernelCodeSigning) && certEKU == ExtKeyUsageCodeSigning) { - return true - } - - return false + (eku == ExtKeyUsageMicrosoftCommercialCodeSigning || eku == ExtKeyUsageMicrosoftKernelCodeSigning) && certEKU == ExtKeyUsageCodeSigning } // isValid performs validity checks on c given that it is a candidate to append @@ -630,8 +646,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V name := string(data) mailbox, ok := parseRFC2821Mailbox(name) if !ok { - // This certificate should not have parsed. - return errors.New("x509: internal error: rfc822Name SAN failed to parse") + return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox) } if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "email address", name, mailbox, @@ -643,6 +658,10 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V case nameTypeDNS: name := string(data) + if _, ok := domainToReverseLabels(name); !ok { + return fmt.Errorf("x509: cannot parse dnsName %q", name) + } + if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "DNS name", name, name, func(parsedName, constraint interface{}) (bool, error) { return matchDomainConstraint(parsedName.(string), constraint.(string)) @@ -716,7 +735,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V for _, caEKU := range c.ExtKeyUsage { comparisonCount++ - if ekuPermittedBy(eku, caEKU) { + if ekuPermittedBy(eku, caEKU, checkingAgainstIssuerCert) { continue NextEKU } } @@ -773,6 +792,18 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V return nil } +// formatOID formats an ASN.1 OBJECT IDENTIFER in the common, dotted style. +func formatOID(oid asn1.ObjectIdentifier) string { + ret := "" + for i, v := range oid { + if i > 0 { + ret += "." + } + ret += strconv.Itoa(v) + } + return ret +} + // Verify attempts to verify c by building one or more chains from c to a // certificate in opts.Roots, using certificates in opts.Intermediates if // needed. If successful, it returns one or more chains where the first @@ -847,16 +878,33 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e } if checkEKU { + foundMatch := false NextUsage: for _, eku := range requestedKeyUsages { for _, leafEKU := range c.ExtKeyUsage { - if ekuPermittedBy(eku, leafEKU) { - continue NextUsage + if ekuPermittedBy(eku, leafEKU, checkingAgainstLeafCert) { + foundMatch = true + break NextUsage } } + } - oid, _ := oidFromExtKeyUsage(eku) - return nil, CertificateInvalidError{c, IncompatibleUsage, fmt.Sprintf("%#v", oid)} + if !foundMatch { + msg := "leaf contains the following, recognized EKUs: " + + for i, leafEKU := range c.ExtKeyUsage { + oid, ok := oidFromExtKeyUsage(leafEKU) + if !ok { + continue + } + + if i > 0 { + msg += ", " + } + msg += formatOID(oid) + } + + return nil, CertificateInvalidError{c, IncompatibleUsage, msg} } } diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go index 86d9e82..ee08dd9 100644 --- a/libgo/go/crypto/x509/x509.go +++ b/libgo/go/crypto/x509/x509.go @@ -706,7 +706,9 @@ type Certificate struct { OCSPServer []string IssuingCertificateURL []string - // Subject Alternate Name values + // Subject Alternate Name values. (Note that these values may not be valid + // if invalid values were contained within a parsed certificate. For + // example, an element of DNSNames may not be a valid DNS domain name.) DNSNames []string EmailAddresses []string IPAddresses []net.IP @@ -1126,17 +1128,9 @@ func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddre err = forEachSAN(value, func(tag int, data []byte) error { switch tag { case nameTypeEmail: - mailbox := string(data) - if _, ok := parseRFC2821Mailbox(mailbox); !ok { - return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox) - } - emailAddresses = append(emailAddresses, mailbox) + emailAddresses = append(emailAddresses, string(data)) case nameTypeDNS: - domain := string(data) - if _, ok := domainToReverseLabels(domain); !ok { - return fmt.Errorf("x509: cannot parse dnsName %q", string(data)) - } - dnsNames = append(dnsNames, domain) + dnsNames = append(dnsNames, string(data)) case nameTypeURI: uri, err := url.Parse(string(data)) if err != nil { @@ -1153,7 +1147,7 @@ func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddre case net.IPv4len, net.IPv6len: ipAddresses = append(ipAddresses, data) default: - return errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(data))) + return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len(data))) } } @@ -2543,7 +2537,7 @@ func ParseCertificateRequest(asn1Data []byte) (*CertificateRequest, error) { func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error) { out := &CertificateRequest{ - Raw: in.Raw, + Raw: in.Raw, RawTBSCertificateRequest: in.TBSCSR.Raw, RawSubjectPublicKeyInfo: in.TBSCSR.PublicKey.Raw, RawSubject: in.TBSCSR.Subject.FullBytes, diff --git a/libgo/go/encoding/json/decode.go b/libgo/go/encoding/json/decode.go index 536f25d..730fb92 100644 --- a/libgo/go/encoding/json/decode.go +++ b/libgo/go/encoding/json/decode.go @@ -443,10 +443,25 @@ func (d *decodeState) valueQuoted() interface{} { // if it encounters an Unmarshaler, indirect stops and returns that. // if decodingNull is true, indirect stops at the last pointer so it can be set to nil. func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { + // Issue #24153 indicates that it is generally not a guaranteed property + // that you may round-trip a reflect.Value by calling Value.Addr().Elem() + // and expect the value to still be settable for values derived from + // unexported embedded struct fields. + // + // The logic below effectively does this when it first addresses the value + // (to satisfy possible pointer methods) and continues to dereference + // subsequent pointers as necessary. + // + // After the first round-trip, we set v back to the original value to + // preserve the original RW flags contained in reflect.Value. + v0 := v + haveAddr := false + // If v is a named type and is addressable, // start with its address, so that if the type has pointer methods, // we find them. if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { + haveAddr = true v = v.Addr() } for { @@ -455,6 +470,7 @@ func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, if v.Kind() == reflect.Interface && !v.IsNil() { e := v.Elem() if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { + haveAddr = false v = e continue } @@ -480,7 +496,13 @@ func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, } } } - v = v.Elem() + + if haveAddr { + v = v0 // restore original value after round-trip Value.Addr().Elem() + haveAddr = false + } else { + v = v.Elem() + } } return nil, nil, v } diff --git a/libgo/go/encoding/json/decode_test.go b/libgo/go/encoding/json/decode_test.go index 34b7ec6..fa1531f 100644 --- a/libgo/go/encoding/json/decode_test.go +++ b/libgo/go/encoding/json/decode_test.go @@ -615,9 +615,9 @@ var unmarshalTests = []unmarshalTest{ out: S5{S8: S8{S9: S9{Y: 2}}}, }, { - in: `{"X": 1,"Y":2}`, - ptr: new(S5), - err: fmt.Errorf("json: unknown field \"X\""), + in: `{"X": 1,"Y":2}`, + ptr: new(S5), + err: fmt.Errorf("json: unknown field \"X\""), disallowUnknownFields: true, }, { @@ -626,9 +626,9 @@ var unmarshalTests = []unmarshalTest{ out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}}, }, { - in: `{"X": 1,"Y":2}`, - ptr: new(S10), - err: fmt.Errorf("json: unknown field \"X\""), + in: `{"X": 1,"Y":2}`, + ptr: new(S10), + err: fmt.Errorf("json: unknown field \"X\""), disallowUnknownFields: true, }, @@ -835,8 +835,8 @@ var unmarshalTests = []unmarshalTest{ "Q": 18, "extra": true }`, - ptr: new(Top), - err: fmt.Errorf("json: unknown field \"extra\""), + ptr: new(Top), + err: fmt.Errorf("json: unknown field \"extra\""), disallowUnknownFields: true, }, { @@ -862,8 +862,8 @@ var unmarshalTests = []unmarshalTest{ "Z": 17, "Q": 18 }`, - ptr: new(Top), - err: fmt.Errorf("json: unknown field \"extra\""), + ptr: new(Top), + err: fmt.Errorf("json: unknown field \"extra\""), disallowUnknownFields: true, }, } @@ -2089,10 +2089,14 @@ func TestInvalidStringOption(t *testing.T) { } } -// Test unmarshal behavior with regards to embedded pointers to unexported structs. -// If unallocated, this returns an error because unmarshal cannot set the field. -// Issue 21357. -func TestUnmarshalEmbeddedPointerUnexported(t *testing.T) { +// Test unmarshal behavior with regards to embedded unexported structs. +// +// (Issue 21357) If the embedded struct is a pointer and is unallocated, +// this returns an error because unmarshal cannot set the field. +// +// (Issue 24152) If the embedded struct is given an explicit name, +// ensure that the normal unmarshal logic does not panic in reflect. +func TestUnmarshalEmbeddedUnexported(t *testing.T) { type ( embed1 struct{ Q int } embed2 struct{ Q int } @@ -2119,6 +2123,18 @@ func TestUnmarshalEmbeddedPointerUnexported(t *testing.T) { *embed3 R int } + S6 struct { + embed1 `json:"embed1"` + } + S7 struct { + embed1 `json:"embed1"` + embed2 + } + S8 struct { + embed1 `json:"embed1"` + embed2 `json:"embed2"` + Q int + } ) tests := []struct { @@ -2154,6 +2170,32 @@ func TestUnmarshalEmbeddedPointerUnexported(t *testing.T) { ptr: new(S5), out: &S5{R: 2}, err: fmt.Errorf("json: cannot set embedded pointer to unexported struct: json.embed3"), + }, { + // Issue 24152, ensure decodeState.indirect does not panic. + in: `{"embed1": {"Q": 1}}`, + ptr: new(S6), + out: &S6{embed1{1}}, + }, { + // Issue 24153, check that we can still set forwarded fields even in + // the presence of a name conflict. + // + // This relies on obscure behavior of reflect where it is possible + // to set a forwarded exported field on an unexported embedded struct + // even though there is a name conflict, even when it would have been + // impossible to do so according to Go visibility rules. + // Go forbids this because it is ambiguous whether S7.Q refers to + // S7.embed1.Q or S7.embed2.Q. Since embed1 and embed2 are unexported, + // it should be impossible for an external package to set either Q. + // + // It is probably okay for a future reflect change to break this. + in: `{"embed1": {"Q": 1}, "Q": 2}`, + ptr: new(S7), + out: &S7{embed1{1}, embed2{2}}, + }, { + // Issue 24153, similar to the S7 case. + in: `{"embed1": {"Q": 1}, "embed2": {"Q": 2}, "Q": 3}`, + ptr: new(S8), + out: &S8{embed1{1}, embed2{2}, 3}, }} for i, tt := range tests { diff --git a/libgo/go/go/internal/srcimporter/srcimporter.go b/libgo/go/go/internal/srcimporter/srcimporter.go index b0dc8ab..9ed7e5e 100644 --- a/libgo/go/go/internal/srcimporter/srcimporter.go +++ b/libgo/go/go/internal/srcimporter/srcimporter.go @@ -44,9 +44,9 @@ func New(ctxt *build.Context, fset *token.FileSet, packages map[string]*types.Pa // for a package that is in the process of being imported. var importing types.Package -// Import(path) is a shortcut for ImportFrom(path, "", 0). +// Import(path) is a shortcut for ImportFrom(path, ".", 0). func (p *Importer) Import(path string) (*types.Package, error) { - return p.ImportFrom(path, "", 0) + return p.ImportFrom(path, ".", 0) // use "." rather than "" (see issue #24441) } // ImportFrom imports the package with the given import path resolved from the given srcDir, @@ -60,23 +60,10 @@ func (p *Importer) ImportFrom(path, srcDir string, mode types.ImportMode) (*type panic("non-zero import mode") } - // determine package path (do vendor resolution) - var bp *build.Package - var err error - switch { - default: - if abs, err := p.absPath(srcDir); err == nil { // see issue #14282 - srcDir = abs - } - bp, err = p.ctxt.Import(path, srcDir, build.FindOnly) - - case build.IsLocalImport(path): - // "./x" -> "srcDir/x" - bp, err = p.ctxt.ImportDir(filepath.Join(srcDir, path), build.FindOnly) - - case p.isAbsPath(path): - return nil, fmt.Errorf("invalid absolute import path %q", path) + if abs, err := p.absPath(srcDir); err == nil { // see issue #14282 + srcDir = abs } + bp, err := p.ctxt.Import(path, srcDir, 0) if err != nil { return nil, err // err may be *build.NoGoError - return as is } @@ -113,11 +100,6 @@ func (p *Importer) ImportFrom(path, srcDir string, mode types.ImportMode) (*type } }() - // collect package files - bp, err = p.ctxt.ImportDir(bp.Dir, 0) - if err != nil { - return nil, err // err may be *build.NoGoError - return as is - } var filenames []string filenames = append(filenames, bp.GoFiles...) filenames = append(filenames, bp.CgoFiles...) diff --git a/libgo/go/go/internal/srcimporter/srcimporter_test.go b/libgo/go/go/internal/srcimporter/srcimporter_test.go index 356e71d..dd4d56a 100644 --- a/libgo/go/go/internal/srcimporter/srcimporter_test.go +++ b/libgo/go/go/internal/srcimporter/srcimporter_test.go @@ -10,6 +10,7 @@ import ( "go/types" "internal/testenv" "io/ioutil" + "path" "path/filepath" "runtime" "strings" @@ -162,3 +163,34 @@ func TestIssue20855(t *testing.T) { t.Error("got no package despite no hard errors") } } + +func testImportPath(t *testing.T, pkgPath string) { + if !testenv.HasSrc() { + t.Skip("no source code available") + } + + pkgName := path.Base(pkgPath) + + pkg, err := importer.Import(pkgPath) + if err != nil { + t.Fatal(err) + } + + if pkg.Name() != pkgName { + t.Errorf("got %q; want %q", pkg.Name(), pkgName) + } + + if pkg.Path() != pkgPath { + t.Errorf("got %q; want %q", pkg.Path(), pkgPath) + } +} + +// TestIssue23092 tests relative imports. +func TestIssue23092(t *testing.T) { + testImportPath(t, "./testdata/issue23092") +} + +// TestIssue24392 tests imports against a path containing 'testdata'. +func TestIssue24392(t *testing.T) { + testImportPath(t, "go/internal/srcimporter/testdata/issue24392") +} diff --git a/libgo/go/go/internal/srcimporter/testdata/issue23092/issue23092.go b/libgo/go/go/internal/srcimporter/testdata/issue23092/issue23092.go new file mode 100644 index 0000000..608698b --- /dev/null +++ b/libgo/go/go/internal/srcimporter/testdata/issue23092/issue23092.go @@ -0,0 +1,5 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package issue23092 diff --git a/libgo/go/go/internal/srcimporter/testdata/issue24392/issue24392.go b/libgo/go/go/internal/srcimporter/testdata/issue24392/issue24392.go new file mode 100644 index 0000000..8ad5221 --- /dev/null +++ b/libgo/go/go/internal/srcimporter/testdata/issue24392/issue24392.go @@ -0,0 +1,5 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package issue24392 diff --git a/libgo/go/internal/singleflight/singleflight.go b/libgo/go/internal/singleflight/singleflight.go index 1e9960d..b2d82e2 100644 --- a/libgo/go/internal/singleflight/singleflight.go +++ b/libgo/go/internal/singleflight/singleflight.go @@ -103,11 +103,21 @@ func (g *Group) doCall(c *call, key string, fn func() (interface{}, error)) { g.mu.Unlock() } -// Forget tells the singleflight to forget about a key. Future calls -// to Do for this key will call the function rather than waiting for -// an earlier call to complete. -func (g *Group) Forget(key string) { +// ForgetUnshared tells the singleflight to forget about a key if it is not +// shared with any other goroutines. Future calls to Do for a forgotten key +// will call the function rather than waiting for an earlier call to complete. +// Returns whether the key was forgotten or unknown--that is, whether no +// other goroutines are waiting for the result. +func (g *Group) ForgetUnshared(key string) bool { g.mu.Lock() - delete(g.m, key) - g.mu.Unlock() + defer g.mu.Unlock() + c, ok := g.m[key] + if !ok { + return true + } + if c.dups == 0 { + delete(g.m, key) + return true + } + return false } diff --git a/libgo/go/net/http/pprof/pprof.go b/libgo/go/net/http/pprof/pprof.go index 21992d6..77e0bcd 100644 --- a/libgo/go/net/http/pprof/pprof.go +++ b/libgo/go/net/http/pprof/pprof.go @@ -80,6 +80,7 @@ func init() { // command line, with arguments separated by NUL bytes. // The package initialization registers it as /debug/pprof/cmdline. func Cmdline(w http.ResponseWriter, r *http.Request) { + w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(w, strings.Join(os.Args, "\x00")) } @@ -100,33 +101,36 @@ func durationExceedsWriteTimeout(r *http.Request, seconds float64) bool { return ok && srv.WriteTimeout != 0 && seconds >= srv.WriteTimeout.Seconds() } +func serveError(w http.ResponseWriter, status int, txt string) { + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + w.Header().Set("X-Go-Pprof", "1") + w.Header().Del("Content-Disposition") + w.WriteHeader(status) + fmt.Fprintln(w, txt) +} + // Profile responds with the pprof-formatted cpu profile. // The package initialization registers it as /debug/pprof/profile. func Profile(w http.ResponseWriter, r *http.Request) { + w.Header().Set("X-Content-Type-Options", "nosniff") sec, _ := strconv.ParseInt(r.FormValue("seconds"), 10, 64) if sec == 0 { sec = 30 } if durationExceedsWriteTimeout(r, float64(sec)) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - w.Header().Set("X-Go-Pprof", "1") - w.WriteHeader(http.StatusBadRequest) - fmt.Fprintln(w, "profile duration exceeds server's WriteTimeout") + serveError(w, http.StatusBadRequest, "profile duration exceeds server's WriteTimeout") return } // Set Content Type assuming StartCPUProfile will work, // because if it does it starts writing. w.Header().Set("Content-Type", "application/octet-stream") + w.Header().Set("Content-Disposition", `attachment; filename="profile"`) if err := pprof.StartCPUProfile(w); err != nil { // StartCPUProfile failed, so no writes yet. - // Can change header back to text content - // and send error code. - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - w.Header().Set("X-Go-Pprof", "1") - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "Could not enable CPU profiling: %s\n", err) + serveError(w, http.StatusInternalServerError, + fmt.Sprintf("Could not enable CPU profiling: %s", err)) return } sleep(w, time.Duration(sec)*time.Second) @@ -137,29 +141,25 @@ func Profile(w http.ResponseWriter, r *http.Request) { // Tracing lasts for duration specified in seconds GET parameter, or for 1 second if not specified. // The package initialization registers it as /debug/pprof/trace. func Trace(w http.ResponseWriter, r *http.Request) { + w.Header().Set("X-Content-Type-Options", "nosniff") sec, err := strconv.ParseFloat(r.FormValue("seconds"), 64) if sec <= 0 || err != nil { sec = 1 } if durationExceedsWriteTimeout(r, sec) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - w.Header().Set("X-Go-Pprof", "1") - w.WriteHeader(http.StatusBadRequest) - fmt.Fprintln(w, "profile duration exceeds server's WriteTimeout") + serveError(w, http.StatusBadRequest, "profile duration exceeds server's WriteTimeout") return } // Set Content Type assuming trace.Start will work, // because if it does it starts writing. w.Header().Set("Content-Type", "application/octet-stream") + w.Header().Set("Content-Disposition", `attachment; filename="trace"`) if err := trace.Start(w); err != nil { // trace.Start failed, so no writes yet. - // Can change header back to text content and send error code. - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - w.Header().Set("X-Go-Pprof", "1") - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "Could not enable tracing: %s\n", err) + serveError(w, http.StatusInternalServerError, + fmt.Sprintf("Could not enable tracing: %s", err)) return } sleep(w, time.Duration(sec*float64(time.Second))) @@ -170,6 +170,7 @@ func Trace(w http.ResponseWriter, r *http.Request) { // responding with a table mapping program counters to function names. // The package initialization registers it as /debug/pprof/symbol. func Symbol(w http.ResponseWriter, r *http.Request) { + w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("Content-Type", "text/plain; charset=utf-8") // We have to read the whole POST body before @@ -222,18 +223,23 @@ func Handler(name string) http.Handler { type handler string func (name handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - debug, _ := strconv.Atoi(r.FormValue("debug")) + w.Header().Set("X-Content-Type-Options", "nosniff") p := pprof.Lookup(string(name)) if p == nil { - w.WriteHeader(404) - fmt.Fprintf(w, "Unknown profile: %s\n", name) + serveError(w, http.StatusNotFound, "Unknown profile") return } gc, _ := strconv.Atoi(r.FormValue("gc")) if name == "heap" && gc > 0 { runtime.GC() } + debug, _ := strconv.Atoi(r.FormValue("debug")) + if debug != 0 { + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + } else { + w.Header().Set("Content-Type", "application/octet-stream") + w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, name)) + } p.WriteTo(w, debug) } diff --git a/libgo/go/net/http/pprof/pprof_test.go b/libgo/go/net/http/pprof/pprof_test.go new file mode 100644 index 0000000..47dd35b --- /dev/null +++ b/libgo/go/net/http/pprof/pprof_test.go @@ -0,0 +1,69 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pprof + +import ( + "bytes" + "io/ioutil" + "net/http" + "net/http/httptest" + "testing" +) + +func TestHandlers(t *testing.T) { + testCases := []struct { + path string + handler http.HandlerFunc + statusCode int + contentType string + contentDisposition string + resp []byte + }{ + {"/debug/pprof/