aboutsummaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-06-07 18:05:45 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-06-07 18:05:45 +0000
commitce311a8cae4489058f8601bebdf511b7fb5fce26 (patch)
tree81494302b4f5708ad6c96bad6ecfd9c109574c38 /libgo
parent48ec607c1f8d1f1783850f1d2729fd23716b1b1b (diff)
parentdc23fb4d72eed9ea09fbf4704b26e0e36414a57a (diff)
downloadgcc-ce311a8cae4489058f8601bebdf511b7fb5fce26.zip
gcc-ce311a8cae4489058f8601bebdf511b7fb5fce26.tar.gz
gcc-ce311a8cae4489058f8601bebdf511b7fb5fce26.tar.bz2
Merge from trunk revision 261284.
From-SVN: r261288
Diffstat (limited to 'libgo')
-rw-r--r--libgo/MERGE2
-rw-r--r--libgo/Makefile.am417
-rw-r--r--libgo/Makefile.in418
-rw-r--r--libgo/VERSION2
-rw-r--r--libgo/check-packages.txt163
-rwxr-xr-xlibgo/configure7
-rw-r--r--libgo/configure.ac7
-rw-r--r--libgo/go/archive/zip/reader.go8
-rw-r--r--libgo/go/archive/zip/reader_test.go2
-rw-r--r--libgo/go/cmd/cgo/main.go2
-rw-r--r--libgo/go/cmd/go/alldocs.go6
-rw-r--r--libgo/go/cmd/go/go_test.go91
-rw-r--r--libgo/go/cmd/go/internal/cfg/cfg.go11
-rw-r--r--libgo/go/cmd/go/internal/get/vcs.go34
-rw-r--r--libgo/go/cmd/go/internal/get/vcs_test.go43
-rw-r--r--libgo/go/cmd/go/internal/help/helpdoc.go6
-rw-r--r--libgo/go/cmd/go/internal/load/pkg.go31
-rw-r--r--libgo/go/cmd/go/internal/test/test.go13
-rw-r--r--libgo/go/cmd/go/internal/vet/vet.go4
-rw-r--r--libgo/go/cmd/go/internal/vet/vetflag.go2
-rw-r--r--libgo/go/cmd/go/internal/work/buildid.go56
-rw-r--r--libgo/go/cmd/go/internal/work/exec.go57
-rw-r--r--libgo/go/cmd/go/internal/work/gccgo.go13
-rw-r--r--libgo/go/cmd/go/internal/work/security.go96
-rw-r--r--libgo/go/cmd/go/internal/work/security_test.go11
-rwxr-xr-xlibgo/go/cmd/go/mkalldocs.sh11
-rw-r--r--libgo/go/cmd/go/mkdoc.sh9
-rw-r--r--libgo/go/cmd/internal/objabi/funcid.go34
-rw-r--r--libgo/go/cmd/vet/main.go12
-rw-r--r--libgo/go/crypto/x509/name_constraints_test.go135
-rw-r--r--libgo/go/crypto/x509/root_aix.go4
-rw-r--r--libgo/go/crypto/x509/verify.go88
-rw-r--r--libgo/go/crypto/x509/x509.go20
-rw-r--r--libgo/go/encoding/json/decode.go24
-rw-r--r--libgo/go/encoding/json/decode_test.go70
-rw-r--r--libgo/go/go/build/build.go44
-rw-r--r--libgo/go/go/build/gc.go137
-rw-r--r--libgo/go/go/build/gccgo.go20
-rw-r--r--libgo/go/go/build/syslist.go2
-rw-r--r--libgo/go/go/internal/gccgoimporter/importer.go2
-rw-r--r--libgo/go/go/internal/srcimporter/srcimporter.go28
-rw-r--r--libgo/go/go/internal/srcimporter/srcimporter_test.go32
-rw-r--r--libgo/go/go/internal/srcimporter/testdata/issue23092/issue23092.go5
-rw-r--r--libgo/go/go/internal/srcimporter/testdata/issue24392/issue24392.go5
-rw-r--r--libgo/go/internal/singleflight/singleflight.go22
-rw-r--r--libgo/go/internal/syscall/unix/getrandom_linux_generic.go2
-rw-r--r--libgo/go/net/http/pprof/pprof.go52
-rw-r--r--libgo/go/net/http/pprof/pprof_test.go69
-rw-r--r--libgo/go/net/lookup.go32
-rw-r--r--libgo/go/net/lookup_test.go25
-rw-r--r--libgo/go/net/tcpsock_unix_test.go1
-rw-r--r--libgo/go/os/signal/signal_cgo_test.go2
-rw-r--r--libgo/go/reflect/all_test.go31
-rw-r--r--libgo/go/reflect/type.go37
-rw-r--r--libgo/go/runtime/crash_test.go3
-rw-r--r--libgo/go/runtime/error.go6
-rw-r--r--libgo/go/runtime/hash32.go2
-rw-r--r--libgo/go/runtime/lfstack_32bit.go2
-rw-r--r--libgo/go/runtime/malloc.go13
-rw-r--r--libgo/go/runtime/panic.go3
-rw-r--r--libgo/go/runtime/proc.go6
-rw-r--r--libgo/go/runtime/stack.go1229
-rw-r--r--libgo/go/runtime/symtab.go29
-rw-r--r--libgo/go/runtime/unaligned2.go2
-rw-r--r--libgo/go/syscall/endian_little.go2
-rw-r--r--libgo/go/syscall/libcall_linux_ustat.go2
-rwxr-xr-xlibgo/goarch.sh7
-rw-r--r--libgo/gotool-packages.txt30
-rw-r--r--libgo/libgo-packages.txt177
-rwxr-xr-xlibgo/match.sh4
-rw-r--r--libgo/misc/cgo/testplugin/src/issue24351/main.go21
-rw-r--r--libgo/misc/cgo/testplugin/src/issue24351/plugin.go14
-rw-r--r--libgo/misc/cgo/testplugin/test.bash5
-rw-r--r--libgo/misc/cgo/testshared/shared_test.go1
-rwxr-xr-xlibgo/mkruntimeinc.sh33
-rwxr-xr-xlibgo/mksysinfo.sh3
-rw-r--r--libgo/runtime/go-unwind.c199
-rw-r--r--libgo/runtime/runtime_c.c59
-rw-r--r--libgo/sysinfo.c209
-rwxr-xr-xlibgo/testsuite/gotest14
80 files changed, 2204 insertions, 2328 deletions
diff --git a/libgo/MERGE b/libgo/MERGE
index 26b8869..6f31fab 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-20e228f2fdb44350c858de941dff4aea9f3127b8
+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/Makefile.am b/libgo/Makefile.am
index 531f8f0..d847413 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -397,8 +397,10 @@ 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
+ 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
@@ -591,34 +593,22 @@ 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
+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
@@ -712,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)) \
@@ -937,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))
@@ -1093,6 +876,7 @@ CHECK_DEPS = \
$(toolexeclibgotext_DATA) \
$(toolexeclibgotexttemplate_DATA) \
$(toolexeclibgounicode_DATA) \
+ $(noinst_DATA) \
$(noinst_LIBRARIES)
if GOC_IS_LLGO
@@ -1153,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
@@ -1176,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)
@@ -1185,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
@@ -1278,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 fbca83e..6b3c597 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -757,8 +757,9 @@ 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 runtime/pprof/internal/profile.gox \
+ 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
@@ -819,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 \
@@ -1041,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))
@@ -1170,7 +962,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.
@@ -1189,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
@@ -1206,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
@@ -1234,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 \
@@ -3171,32 +2803,20 @@ 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
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
@@ -3323,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/VERSION b/libgo/VERSION
index dc3cdca..98736c7 100644
--- a/libgo/VERSION
+++ b/libgo/VERSION
@@ -1 +1 @@
-go1.10rc2
+go1.10.2
diff --git a/libgo/check-packages.txt b/libgo/check-packages.txt
new file mode 100644
index 0000000..82a08c6
--- /dev/null
+++ b/libgo/check-packages.txt
@@ -0,0 +1,163 @@
+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/http/pprof
+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/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/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/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/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/go_test.go b/libgo/go/cmd/go/go_test.go
index c5a3d7b..f6d6f42 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()
@@ -3223,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()
@@ -3233,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()
@@ -3243,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()
@@ -3253,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()
@@ -3271,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)
@@ -5105,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)
@@ -5798,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()
@@ -5955,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/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/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/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 ac764b4..882b86d 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"
@@ -224,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
@@ -895,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
@@ -976,7 +965,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)
}
@@ -1021,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]) {
@@ -1030,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")
@@ -1097,9 +1088,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(),
@@ -1224,6 +1212,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
@@ -1238,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.
@@ -1610,9 +1599,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 +1627,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..72415cc 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))
@@ -671,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)
}
@@ -862,9 +872,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/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/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/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go
index e2ae850..733938e 100644
--- a/libgo/go/cmd/go/internal/work/buildid.go
+++ b/libgo/go/cmd/go/internal/work/buildid.go
@@ -235,6 +235,8 @@ func (b *Builder) gccgoToolID(name, language string) (string, error) {
cmdline := str.StringList(cfg.BuildToolexec, name, "-###", "-x", language, "-c", "-")
cmd := exec.Command(cmdline[0], cmdline[1:]...)
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)
@@ -292,13 +294,36 @@ 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
- fmt.Fprintf(&buf, "\t"+`.section .go.buildid,"e"`+"\n")
+ if cfg.Goos != "solaris" || assemblerIsGas() {
+ fmt.Fprintf(&buf, "\t"+`.section .go.buildid,"e"`+"\n")
+ } 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++ {
if i > 0 {
@@ -311,8 +336,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")) {
@@ -434,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
@@ -519,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.
@@ -547,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
}
}
@@ -557,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 5527e90..5994dbc 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.
@@ -944,16 +956,29 @@ 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
+ 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) {
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 +988,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
}
}
@@ -1090,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)
}
@@ -1540,6 +1565,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 {
@@ -1580,13 +1607,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/cmd/go/internal/work/gccgo.go b/libgo/go/cmd/go/internal/work/gccgo.go
index 72d4d9d..e8dab19 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", arArgs, "rc", 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")
diff --git a/libgo/go/cmd/go/internal/work/security.go b/libgo/go/cmd/go/internal/work/security.go
index fee5bee..5c67aa9 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,27 +46,65 @@ 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`),
+ 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(`-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(`-?-std=([^@\-].*)`),
+ re(`-?-stdlib=([^@\-].*)`),
+ re(`-w`),
re(`-x([^@\-].*)`),
}
var validCompilerFlagsWithNextArg = []string{
+ "-arch",
"-D",
"-I",
"-framework",
+ "-isysroot",
+ "-isystem",
+ "--sysroot",
+ "-target",
"-x",
}
@@ -73,29 +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,-rpath,([^,@\-][^,]+)`),
+ 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,-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_].*\.(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{
+ "-arch",
"-F",
"-l",
"-L",
"-framework",
+ "-isysroot",
+ "--sysroot",
+ "-target",
+ "-Wl,-framework",
+ "-Wl,-rpath",
+ "-Wl,-undefined",
}
func checkCompilerFlags(name, source string, list []string) error {
@@ -147,10 +222,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..bd898c9 100644
--- a/libgo/go/cmd/go/internal/work/security_test.go
+++ b/libgo/go/cmd/go/internal/work/security_test.go
@@ -132,14 +132,14 @@ var goodLinkerFlags = [][]string{
{"-l", "世界"},
{"-L", "framework"},
{"-framework", "Chocolate"},
+ {"-Wl,-framework", "-Wl,Chocolate"},
+ {"-Wl,-framework,Chocolate"},
+ {"-Wl,-unresolved-symbols=ignore-all"},
}
var badLinkerFlags = [][]string{
{"-DFOO"},
{"-Dfoo=bar"},
- {"-O"},
- {"-O2"},
- {"-Osmall"},
{"-W"},
{"-Wall"},
{"-fobjc-arc"},
@@ -152,7 +152,6 @@ var badLinkerFlags = [][]string{
{"-fno-stack-xxx"},
{"-mstack-overflow"},
{"-mno-stack-overflow"},
- {"-mmacosx-version"},
{"-mnop-fun-dllimport"},
{"-std=c99"},
{"-xc"},
@@ -185,6 +184,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"},
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
-
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/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/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/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",
+}
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/build/build.go b/libgo/go/go/build/build.go
index 7902404..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
@@ -1595,14 +1608,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..e2be2cb
--- /dev/null
+++ b/libgo/go/go/build/gc.go
@@ -0,0 +1,137 @@
+// 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 (
+ "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
new file mode 100644
index 0000000..59e089d
--- /dev/null
+++ b/libgo/go/go/build/gccgo.go
@@ -0,0 +1,20 @@
+// 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)
+}
+
+// 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]
+}
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/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 {
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/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/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/<script>scripty<script>", Index, http.StatusNotFound, "text/plain; charset=utf-8", "", []byte("Unknown profile\n")},
+ {"/debug/pprof/heap", Index, http.StatusOK, "application/octet-stream", `attachment; filename="heap"`, nil},
+ {"/debug/pprof/heap?debug=1", Index, http.StatusOK, "text/plain; charset=utf-8", "", nil},
+ {"/debug/pprof/cmdline", Cmdline, http.StatusOK, "text/plain; charset=utf-8", "", nil},
+ {"/debug/pprof/profile?seconds=1", Profile, http.StatusOK, "application/octet-stream", `attachment; filename="profile"`, nil},
+ {"/debug/pprof/symbol", Symbol, http.StatusOK, "text/plain; charset=utf-8", "", nil},
+ {"/debug/pprof/trace", Trace, http.StatusOK, "application/octet-stream", `attachment; filename="trace"`, nil},
+ }
+ for _, tc := range testCases {
+ t.Run(tc.path, func(t *testing.T) {
+ req := httptest.NewRequest("GET", "http://example.com"+tc.path, nil)
+ w := httptest.NewRecorder()
+ tc.handler(w, req)
+
+ resp := w.Result()
+ if got, want := resp.StatusCode, tc.statusCode; got != want {
+ t.Errorf("status code: got %d; want %d", got, want)
+ }
+
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ t.Errorf("when reading response body, expected non-nil err; got %v", err)
+ }
+ if got, want := resp.Header.Get("X-Content-Type-Options"), "nosniff"; got != want {
+ t.Errorf("X-Content-Type-Options: got %q; want %q", got, want)
+ }
+ if got, want := resp.Header.Get("Content-Type"), tc.contentType; got != want {
+ t.Errorf("Content-Type: got %q; want %q", got, want)
+ }
+ if got, want := resp.Header.Get("Content-Disposition"), tc.contentDisposition; got != want {
+ t.Errorf("Content-Disposition: got %q; want %q", got, want)
+ }
+
+ if resp.StatusCode == http.StatusOK {
+ return
+ }
+ if got, want := resp.Header.Get("X-Go-Pprof"), "1"; got != want {
+ t.Errorf("X-Go-Pprof: got %q; want %q", got, want)
+ }
+ if !bytes.Equal(body, tc.resp) {
+ t.Errorf("response: got %q; want %q", body, tc.resp)
+ }
+ })
+ }
+
+}
diff --git a/libgo/go/net/lookup.go b/libgo/go/net/lookup.go
index 85e4729..a65b735 100644
--- a/libgo/go/net/lookup.go
+++ b/libgo/go/net/lookup.go
@@ -194,10 +194,16 @@ func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, err
resolverFunc = alt
}
+ // We don't want a cancelation of ctx to affect the
+ // lookupGroup operation. Otherwise if our context gets
+ // canceled it might cause an error to be returned to a lookup
+ // using a completely different context.
+ lookupGroupCtx, lookupGroupCancel := context.WithCancel(context.Background())
+
dnsWaitGroup.Add(1)
ch, called := lookupGroup.DoChan(host, func() (interface{}, error) {
defer dnsWaitGroup.Done()
- return testHookLookupIP(ctx, resolverFunc, host)
+ return testHookLookupIP(lookupGroupCtx, resolverFunc, host)
})
if !called {
dnsWaitGroup.Done()
@@ -205,20 +211,28 @@ func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, err
select {
case <-ctx.Done():
- // If the DNS lookup timed out for some reason, force
- // future requests to start the DNS lookup again
- // rather than waiting for the current lookup to
- // complete. See issue 8602.
- ctxErr := ctx.Err()
- if ctxErr == context.DeadlineExceeded {
- lookupGroup.Forget(host)
+ // Our context was canceled. If we are the only
+ // goroutine looking up this key, then drop the key
+ // from the lookupGroup and cancel the lookup.
+ // If there are other goroutines looking up this key,
+ // let the lookup continue uncanceled, and let later
+ // lookups with the same key share the result.
+ // See issues 8602, 20703, 22724.
+ if lookupGroup.ForgetUnshared(host) {
+ lookupGroupCancel()
+ } else {
+ go func() {
+ <-ch
+ lookupGroupCancel()
+ }()
}
- err := mapErr(ctxErr)
+ err := mapErr(ctx.Err())
if trace != nil && trace.DNSDone != nil {
trace.DNSDone(nil, false, err)
}
return nil, err
case r := <-ch:
+ lookupGroupCancel()
if trace != nil && trace.DNSDone != nil {
addrs, _ := r.Val.([]IPAddr)
trace.DNSDone(ipAddrsEface(addrs), r.Shared, r.Err)
diff --git a/libgo/go/net/lookup_test.go b/libgo/go/net/lookup_test.go
index bfb8725..24787cc 100644
--- a/libgo/go/net/lookup_test.go
+++ b/libgo/go/net/lookup_test.go
@@ -791,3 +791,28 @@ func TestLookupNonLDH(t *testing.T) {
t.Fatalf("lookup error = %v, want %v", err, errNoSuchHost)
}
}
+
+func TestLookupContextCancel(t *testing.T) {
+ if testenv.Builder() == "" {
+ testenv.MustHaveExternalNetwork(t)
+ }
+ if runtime.GOOS == "nacl" {
+ t.Skip("skip on nacl")
+ }
+
+ defer dnsWaitGroup.Wait()
+
+ ctx, ctxCancel := context.WithCancel(context.Background())
+ ctxCancel()
+ _, err := DefaultResolver.LookupIPAddr(ctx, "google.com")
+ if err != errCanceled {
+ testenv.SkipFlakyNet(t)
+ t.Fatal(err)
+ }
+ ctx = context.Background()
+ _, err = DefaultResolver.LookupIPAddr(ctx, "google.com")
+ if err != nil {
+ testenv.SkipFlakyNet(t)
+ t.Fatal(err)
+ }
+}
diff --git a/libgo/go/net/tcpsock_unix_test.go b/libgo/go/net/tcpsock_unix_test.go
index 3af1834..95c02d2 100644
--- a/libgo/go/net/tcpsock_unix_test.go
+++ b/libgo/go/net/tcpsock_unix_test.go
@@ -87,6 +87,7 @@ func TestTCPSpuriousConnSetupCompletionWithCancel(t *testing.T) {
if testenv.Builder() == "" {
testenv.MustHaveExternalNetwork(t)
}
+ defer dnsWaitGroup.Wait()
t.Parallel()
const tries = 10000
var wg sync.WaitGroup
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
diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go
index 3070aac..96b57ef 100644
--- a/libgo/go/reflect/all_test.go
+++ b/libgo/go/reflect/all_test.go
@@ -3928,8 +3928,8 @@ func TestOverflow(t *testing.T) {
}
}
-func checkSameType(t *testing.T, x, y interface{}) {
- if TypeOf(x) != TypeOf(y) {
+func checkSameType(t *testing.T, x Type, y interface{}) {
+ if x != TypeOf(y) || TypeOf(Zero(x).Interface()) != TypeOf(y) {
t.Errorf("did not find preexisting type for %s (vs %s)", TypeOf(x), TypeOf(y))
}
}
@@ -4058,7 +4058,7 @@ func TestArrayOf(t *testing.T) {
// check that type already in binary is found
type T int
- checkSameType(t, Zero(ArrayOf(5, TypeOf(T(1)))).Interface(), [5]T{})
+ checkSameType(t, ArrayOf(5, TypeOf(T(1))), [5]T{})
}
func TestArrayOfGC(t *testing.T) {
@@ -4195,7 +4195,7 @@ func TestSliceOf(t *testing.T) {
// check that type already in binary is found
type T1 int
- checkSameType(t, Zero(SliceOf(TypeOf(T1(1)))).Interface(), []T1{})
+ checkSameType(t, SliceOf(TypeOf(T1(1))), []T1{})
}
func TestSliceOverflow(t *testing.T) {
@@ -4410,7 +4410,18 @@ func TestStructOf(t *testing.T) {
})
})
// check that type already in binary is found
- checkSameType(t, Zero(StructOf(fields[2:3])).Interface(), struct{ Y uint64 }{})
+ checkSameType(t, StructOf(fields[2:3]), struct{ Y uint64 }{})
+
+ // gccgo used to fail this test.
+ type structFieldType interface{}
+ checkSameType(t,
+ StructOf([]StructField{
+ StructField{
+ Name: "F",
+ Type: TypeOf((*structFieldType)(nil)).Elem(),
+ },
+ }),
+ struct{ F structFieldType }{})
}
func TestStructOfExportRules(t *testing.T) {
@@ -4963,7 +4974,7 @@ func TestChanOf(t *testing.T) {
// check that type already in binary is found
type T1 int
- checkSameType(t, Zero(ChanOf(BothDir, TypeOf(T1(1)))).Interface(), (chan T1)(nil))
+ checkSameType(t, ChanOf(BothDir, TypeOf(T1(1))), (chan T1)(nil))
}
func TestChanOfDir(t *testing.T) {
@@ -4974,8 +4985,8 @@ func TestChanOfDir(t *testing.T) {
// check that type already in binary is found
type T1 int
- checkSameType(t, Zero(ChanOf(RecvDir, TypeOf(T1(1)))).Interface(), (<-chan T1)(nil))
- checkSameType(t, Zero(ChanOf(SendDir, TypeOf(T1(1)))).Interface(), (chan<- T1)(nil))
+ checkSameType(t, ChanOf(RecvDir, TypeOf(T1(1))), (<-chan T1)(nil))
+ checkSameType(t, ChanOf(SendDir, TypeOf(T1(1))), (chan<- T1)(nil))
// check String form of ChanDir
if crt.ChanDir().String() != "<-chan" {
@@ -5051,7 +5062,7 @@ func TestMapOf(t *testing.T) {
}
// check that type already in binary is found
- checkSameType(t, Zero(MapOf(TypeOf(V(0)), TypeOf(K("")))).Interface(), map[V]K(nil))
+ checkSameType(t, MapOf(TypeOf(V(0)), TypeOf(K(""))), map[V]K(nil))
// check that invalid key type panics
shouldPanic(func() { MapOf(TypeOf((func())(nil)), TypeOf(false)) })
@@ -5181,7 +5192,7 @@ func TestFuncOf(t *testing.T) {
{in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false), TypeOf("")}, want: (func(int) (bool, string))(nil)},
}
for _, tt := range testCases {
- checkSameType(t, Zero(FuncOf(tt.in, tt.out, tt.variadic)).Interface(), tt.want)
+ checkSameType(t, FuncOf(tt.in, tt.out, tt.variadic), tt.want)
}
// check that variadic requires last element be a slice.
diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go
index 6b082c1..07fe4d0 100644
--- a/libgo/go/reflect/type.go
+++ b/libgo/go/reflect/type.go
@@ -1475,8 +1475,10 @@ func ChanOf(dir ChanDir, t Type) Type {
ch.uncommonType = nil
ch.ptrToThis = nil
- ti, _ := lookupCache.LoadOrStore(ckey, &ch.rtype)
- return ti.(Type)
+ // Canonicalize before storing in lookupCache
+ ti := toType(&ch.rtype)
+ lookupCache.Store(ckey, ti.(*rtype))
+ return ti
}
func ismapkey(*rtype) bool // implemented in runtime
@@ -1537,8 +1539,10 @@ func MapOf(key, elem Type) Type {
mt.reflexivekey = isReflexive(ktyp)
mt.needkeyupdate = needKeyUpdate(ktyp)
- ti, _ := lookupCache.LoadOrStore(ckey, &mt.rtype)
- return ti.(Type)
+ // Canonicalize before storing in lookupCache
+ ti := toType(&mt.rtype)
+ lookupCache.Store(ckey, ti.(*rtype))
+ return ti
}
// FuncOf returns the function type with the given argument and result types.
@@ -1621,7 +1625,10 @@ func FuncOf(in, out []Type, variadic bool) Type {
ft.string = &str
ft.uncommonType = nil
ft.ptrToThis = nil
- return addToCache(&ft.rtype)
+
+ // Canonicalize before storing in funcLookupCache
+ tc := toType(&ft.rtype)
+ return addToCache(tc.(*rtype))
}
// funcStr builds a string representation of a funcType.
@@ -1855,8 +1862,10 @@ func SliceOf(t Type) Type {
slice.uncommonType = nil
slice.ptrToThis = nil
- ti, _ := lookupCache.LoadOrStore(ckey, &slice.rtype)
- return ti.(Type)
+ // Canonicalize before storing in lookupCache
+ ti := toType(&slice.rtype)
+ lookupCache.Store(ckey, ti.(*rtype))
+ return ti
}
// The structLookupCache caches StructOf lookups.
@@ -1903,7 +1912,7 @@ func isValidFieldName(fieldName string) bool {
// This limitation may be lifted in a future version.
func StructOf(fields []StructField) Type {
var (
- hash = uint32(0)
+ hash = uint32(12)
size uintptr
typalign int8
comparable = true
@@ -1988,7 +1997,7 @@ func StructOf(fields []StructField) Type {
}
fset[name] = struct{}{}
- repr = append(repr, (" " + ft.String())...)
+ repr = append(repr, (" " + *ft.string)...)
if f.tag != nil {
repr = append(repr, (" " + strconv.Quote(*f.tag))...)
}
@@ -2172,7 +2181,9 @@ func StructOf(fields []StructField) Type {
typ.uncommonType = nil
typ.ptrToThis = nil
- return addToCache(&typ.rtype)
+ // Canonicalize before storing in structLookupCache
+ ti := toType(&typ.rtype)
+ return addToCache(ti.(*rtype))
}
func runtimeStructField(field StructField) structField {
@@ -2400,8 +2411,10 @@ func ArrayOf(count int, elem Type) Type {
}
}
- ti, _ := lookupCache.LoadOrStore(ckey, &array.rtype)
- return ti.(Type)
+ // Canonicalize before storing in lookupCache
+ ti := toType(&array.rtype)
+ lookupCache.Store(ckey, ti.(*rtype))
+ return ti
}
func appendVarint(x []byte, v uintptr) []byte {
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 {
diff --git a/libgo/go/runtime/error.go b/libgo/go/runtime/error.go
index 34b7d37..1a038cf 100644
--- a/libgo/go/runtime/error.go
+++ b/libgo/go/runtime/error.go
@@ -139,14 +139,12 @@ func typestring(x interface{}) string {
}
// printany prints an argument passed to panic.
+// If panic is called with a value that has a String or Error method,
+// it has already been converted into a string by preprintpanics.
func printany(i interface{}) {
switch v := i.(type) {
case nil:
print("nil")
- case stringer:
- print(v.String())
- case error:
- print(v.Error())
case bool:
print(v)
case int:
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/malloc.go b/libgo/go/runtime/malloc.go
index c27aa48..c8d5284 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<<42) | uintptrMask&(0xa0<<52)
+ } else {
+ p = uintptr(i)<<42 | 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
}
}
diff --git a/libgo/go/runtime/panic.go b/libgo/go/runtime/panic.go
index fbdb17e..6b490b7 100644
--- a/libgo/go/runtime/panic.go
+++ b/libgo/go/runtime/panic.go
@@ -384,7 +384,6 @@ func Goexit() {
// Call all Error and String methods before freezing the world.
// Used when crashing with panicking.
-// This must match types handled by printany.
func preprintpanics(p *_panic) {
defer func() {
if recover() != nil {
@@ -410,8 +409,6 @@ func printpanics(p *_panic) {
print("\t")
}
print("panic: ")
- // Because of preprintpanics, p.arg cannot be an error or
- // stringer, so this won't call into user code.
printany(p.arg)
if p.recovered {
print(" [recovered]")
diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go
index 20fa0ad..a6746c9 100644
--- a/libgo/go/runtime/proc.go
+++ b/libgo/go/runtime/proc.go
@@ -423,6 +423,12 @@ func releaseSudog(s *sudog) {
// funcPC returns the entry PC of the function f.
// It assumes that f is a func value. Otherwise the behavior is undefined.
+// CAREFUL: In programs with plugins, funcPC can return different values
+// for the same function (because there are actually multiple copies of
+// the same function in the address space). To be safe, don't use the
+// results of this function in any == expression. It is only safe to
+// use the result as an address at which to start executing code.
+//
// For gccgo note that this differs from the gc implementation; the gc
// implementation adds sys.PtrSize to the address of the interface
// value, but GCC's alias analysis decides that that can not be a
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<<s < x {
- s++
- }
- return 1 << s
-}
-
-// Called from runtime·morestack when more stack is needed.
-// Allocate larger stack and relocate to new stack.
-// Stack growth is multiplicative, for constant amortized cost.
-//
-// g->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")
- })
-}
diff --git a/libgo/go/runtime/symtab.go b/libgo/go/runtime/symtab.go
index 3d15fc8..12dc672 100644
--- a/libgo/go/runtime/symtab.go
+++ b/libgo/go/runtime/symtab.go
@@ -115,6 +115,35 @@ type Func struct {
entry uintptr
}
+// 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 cmd/internal/objabi/funcid.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
+)
+
// FuncForPC returns a *Func describing the function that contains the
// given program counter address, or else nil.
//
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/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/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/misc/cgo/testplugin/src/issue24351/main.go b/libgo/misc/cgo/testplugin/src/issue24351/main.go
new file mode 100644
index 0000000..4107adf
--- /dev/null
+++ b/libgo/misc/cgo/testplugin/src/issue24351/main.go
@@ -0,0 +1,21 @@
+// 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 main
+
+import "plugin"
+
+func main() {
+ p, err := plugin.Open("issue24351.so")
+ if err != nil {
+ panic(err)
+ }
+ f, err := p.Lookup("B")
+ if err != nil {
+ panic(err)
+ }
+ c := make(chan bool)
+ f.(func(chan bool))(c)
+ <-c
+}
diff --git a/libgo/misc/cgo/testplugin/src/issue24351/plugin.go b/libgo/misc/cgo/testplugin/src/issue24351/plugin.go
new file mode 100644
index 0000000..db17e0a
--- /dev/null
+++ b/libgo/misc/cgo/testplugin/src/issue24351/plugin.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.
+
+package main
+
+import "fmt"
+
+func B(c chan bool) {
+ go func() {
+ fmt.Println(1.5)
+ c <- true
+ }()
+}
diff --git a/libgo/misc/cgo/testplugin/test.bash b/libgo/misc/cgo/testplugin/test.bash
index 18e3803..df38204 100644
--- a/libgo/misc/cgo/testplugin/test.bash
+++ b/libgo/misc/cgo/testplugin/test.bash
@@ -85,3 +85,8 @@ GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22175 src/issue22175/main.
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue.22295.so issue22295.pkg
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22295 src/issue22295.pkg/main.go
./issue22295
+
+# Test for issue 24351
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue24351.so src/issue24351/plugin.go
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue24351 src/issue24351/main.go
+./issue24351
diff --git a/libgo/misc/cgo/testshared/shared_test.go b/libgo/misc/cgo/testshared/shared_test.go
index cf049ec..a296005 100644
--- a/libgo/misc/cgo/testshared/shared_test.go
+++ b/libgo/misc/cgo/testshared/shared_test.go
@@ -790,6 +790,7 @@ func TestRebuilding(t *testing.T) {
// If the .a file is newer than the .so, the .so is rebuilt (but not the .a)
t.Run("newarchive", func(t *testing.T) {
resetFileStamps()
+ AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a"))
goCmd(t, "list", "-linkshared", "-f={{.ImportPath}} {{.Stale}} {{.StaleReason}} {{.Target}}", "depBase")
AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a"))
cleanup := touch(t, filepath.Join(gopathInstallDir, "depBase.a"))
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
diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh
index 6f7cba7..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 ' | \
@@ -1142,7 +1143,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
diff --git a/libgo/runtime/go-unwind.c b/libgo/runtime/go-unwind.c
index 4c9fb49..a059acb 100644
--- a/libgo/runtime/go-unwind.c
+++ b/libgo/runtime/go-unwind.c
@@ -10,11 +10,30 @@
#include <unistd.h>
#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,182 @@ 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 *)
+
+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:
+ {
+ int16_t result;
+ __builtin_memcpy (&result, p, sizeof(int16_t));
+ decoded = result;
+ p += sizeof(int16_t);
+ break;
+ }
+ case DW_EH_PE_udata2:
+ {
+ 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:
+ {
+ 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:
+ {
+ 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;
+ 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:
+ __builtin_memcpy (&decoded, (const void *)p, sizeof(const void*));
+ 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. */
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)
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 <sys/epoll.h>
+#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 <sys/ptrace.h>
+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
diff --git a/libgo/testsuite/gotest b/libgo/testsuite/gotest
index 06848fd..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
@@ -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/'