This patch updates libgo to the Go1.10beta1 release.  The final Go
1.10 release is expected around February 1, so it's not clear how the
release timing is going to work with GCC 8.  In any case this updates
GCC to something pretty close to the final Go 1.10 release.

A few changes to the frontend were required to match changes in the
runtime map code, and to handle some no-writebarrier cases in the
runtime package.

As usual with these updates the complete patch is too large to include
in this e-mail message.  I've just included the changes to
gccgo-specific code.

Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian

2018-01-08  Ian Lance Taylor  <i...@golang.org>

* Makefile.am (go_cmd_vet_files): New variable.
(go_cmd_buildid_files, go_cmd_test2json_files): New variables.
(s-zdefaultcc): Change from constants to functions.
(noinst_PROGRAMS): Add vet, buildid, and test2json.
(cgo$(EXEEXT)): Link against $(LIBGOTOOL).
(vet$(EXEEXT)): New target.
(buildid$(EXEEXT)): New target.
(test2json$(EXEEXT)): New target.
(install-exec-local): Install all $(noinst_PROGRAMS).
(uninstall-local): Uninstasll all $(noinst_PROGRAMS).
(check-go-tool): Depend on $(noinst_PROGRAMS).  Copy down
objabi.go.
(check-runtime): Depend on $(noinst_PROGRAMS).
(check-cgo-test, check-carchive-test): Likewise.
(check-vet): New target.
(check): Depend on check-vet.  Look at cmd_vet-testlog.
(.PHONY): Add check-vet.
* Makefile.in: Rebuild.
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE     (revision 256306)
+++ gcc/go/gofrontend/MERGE     (working copy)
@@ -1,4 +1,4 @@
-1319f36ccc65cf802b8e17ddd3d2da3ca6d82f4c
+dbc0c7e4329aada2ae3554c20cfb8cfa48041213
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc    (revision 256262)
+++ gcc/go/gofrontend/expressions.cc    (working copy)
@@ -7483,6 +7483,7 @@ Builtin_call_expression::lower_make(Stat
          return Expression::make_error(this->location());
        }
       len_arg = Expression::make_integer_ul(0, NULL, loc);
+      len_small = true;
     }
   else
     {
@@ -7551,9 +7552,23 @@ Builtin_call_expression::lower_make(Stat
   else if (is_map)
     {
       Expression* type_arg = Expression::make_type_descriptor(type, type_loc);
-      call = Runtime::make_call(Runtime::MAKEMAP, loc, 4, type_arg, len_arg,
-                               Expression::make_nil(loc),
-                               Expression::make_nil(loc));
+      if (!len_small)
+       call = Runtime::make_call(Runtime::MAKEMAP64, loc, 3, type_arg,
+                                 len_arg,
+                                 Expression::make_nil(loc));
+      else
+       {
+         Numeric_constant nclen;
+         unsigned long vlen;
+         if (len_arg->numeric_constant_value(&nclen)
+             && nclen.to_unsigned_long(&vlen) == Numeric_constant::NC_UL_VALID
+             && vlen <= Map_type::bucket_size)
+           call = Runtime::make_call(Runtime::MAKEMAP_SMALL, loc, 0);
+         else
+           call = Runtime::make_call(Runtime::MAKEMAP, loc, 3, type_arg,
+                                     len_arg,
+                                     Expression::make_nil(loc));
+       }
     }
   else if (is_chan)
     {
@@ -9503,14 +9518,8 @@ Call_expression::do_lower(Gogo* gogo, Na
   // could implement them in normal code, but then we would have to
   // explicitly unwind the stack.  These functions are intended to be
   // efficient.  Note that this technique obviously only works for
-  // direct calls, but that is the only way they are used.  The actual
-  // argument to these functions is always the address of a parameter;
-  // we don't need that for the GCC builtin functions, so we just
-  // ignore it.
-  if (gogo->compiling_runtime()
-      && this->args_ != NULL
-      && this->args_->size() == 1
-      && gogo->package_name() == "runtime")
+  // direct calls, but that is the only way they are used.
+  if (gogo->compiling_runtime() && gogo->package_name() == "runtime")
     {
       Func_expression* fe = this->fn_->func_expression();
       if (fe != NULL
@@ -9518,15 +9527,21 @@ Call_expression::do_lower(Gogo* gogo, Na
          && fe->named_object()->package() == NULL)
        {
          std::string n = Gogo::unpack_hidden_name(fe->named_object()->name());
-         if (n == "getcallerpc")
+         if ((this->args_ == NULL || this->args_->size() == 0)
+             && n == "getcallerpc")
            {
              static Named_object* builtin_return_address;
              return this->lower_to_builtin(&builtin_return_address,
                                            "__builtin_return_address",
                                            0);
            }
-         else if (n == "getcallersp")
+         else if (this->args_ != NULL
+                  && this->args_->size() == 1
+                  && n == "getcallersp")
            {
+             // The actual argument to getcallersp is always the
+             // address of a parameter; we don't need that for the
+             // GCC builtin function, so we just ignore it.
              static Named_object* builtin_frame_address;
              return this->lower_to_builtin(&builtin_frame_address,
                                            "__builtin_frame_address",
@@ -10027,7 +10042,7 @@ Call_expression::do_check_types(Gogo*)
     }
 
   const Typed_identifier_list* parameters = fntype->parameters();
-  if (this->args_ == NULL)
+  if (this->args_ == NULL || this->args_->size() == 0)
     {
       if (parameters != NULL && !parameters->empty())
        this->report_error(_("not enough arguments"));
Index: gcc/go/gofrontend/runtime.def
===================================================================
--- gcc/go/gofrontend/runtime.def       (revision 256262)
+++ gcc/go/gofrontend/runtime.def       (working copy)
@@ -91,9 +91,14 @@ DEF_GO_RUNTIME(MAKESLICE64, "runtime.mak
               R1(SLICE))
 
 
-// Make a map.
-DEF_GO_RUNTIME(MAKEMAP, "runtime.makemap", P4(TYPE, INT64, POINTER, POINTER),
-              R1(MAP))
+// Make a map with a hint and an (optional, unused) map structure.
+DEF_GO_RUNTIME(MAKEMAP, "runtime.makemap", P3(TYPE, INT, POINTER),
+               R1(MAP))
+DEF_GO_RUNTIME(MAKEMAP64, "runtime.makemap64", P3(TYPE, INT64, POINTER),
+               R1(MAP))
+
+// Make a map with no hint, or a small constant hint.
+DEF_GO_RUNTIME(MAKEMAP_SMALL, "runtime.makemap_small", P0(), R1(MAP))
 
 // Build a map from a composite literal.
 DEF_GO_RUNTIME(CONSTRUCT_MAP, "__go_construct_map",
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc  (revision 256262)
+++ gcc/go/gofrontend/types.cc  (working copy)
@@ -7830,7 +7830,7 @@ Map_type::do_get_backend(Gogo* gogo)
       bfields[7].btype = uintptr_type->get_backend(gogo);
       bfields[7].location = bloc;
 
-      bfields[8].name = "overflow";
+      bfields[8].name = "extra";
       bfields[8].btype = bpvt;
       bfields[8].location = bloc;
 
@@ -8144,21 +8144,23 @@ Map_type::hmap_type(Type* bucket_type)
 
   Type* int_type = Type::lookup_integer_type("int");
   Type* uint8_type = Type::lookup_integer_type("uint8");
+  Type* uint16_type = Type::lookup_integer_type("uint16");
   Type* uint32_type = Type::lookup_integer_type("uint32");
   Type* uintptr_type = Type::lookup_integer_type("uintptr");
   Type* void_ptr_type = Type::make_pointer_type(Type::make_void_type());
 
   Type* ptr_bucket_type = Type::make_pointer_type(bucket_type);
 
-  Struct_type* ret = make_builtin_struct_type(8,
+  Struct_type* ret = make_builtin_struct_type(9,
                                              "count", int_type,
                                              "flags", uint8_type,
                                              "B", uint8_type,
+                                             "noverflow", uint16_type,
                                              "hash0", uint32_type,
                                              "buckets", ptr_bucket_type,
                                              "oldbuckets", ptr_bucket_type,
                                              "nevacuate", uintptr_type,
-                                             "overflow", void_ptr_type);
+                                             "extra", void_ptr_type);
   ret->set_is_struct_incomparable();
   this->hmap_type_ = ret;
   return ret;
@@ -8191,18 +8193,22 @@ Map_type::hiter_type(Gogo* gogo)
   Type* hmap_type = this->hmap_type(bucket_type);
   Type* hmap_ptr_type = Type::make_pointer_type(hmap_type);
   Type* void_ptr_type = Type::make_pointer_type(Type::make_void_type());
+  Type* bool_type = Type::lookup_bool_type();
 
-  Struct_type* ret = make_builtin_struct_type(12,
+  Struct_type* ret = make_builtin_struct_type(15,
                                              "key", key_ptr_type,
                                              "val", val_ptr_type,
                                              "t", uint8_ptr_type,
                                              "h", hmap_ptr_type,
                                              "buckets", bucket_ptr_type,
                                              "bptr", bucket_ptr_type,
-                                             "overflow0", void_ptr_type,
-                                             "overflow1", void_ptr_type,
+                                             "overflow", void_ptr_type,
+                                             "oldoverflow", void_ptr_type,
                                              "startBucket", uintptr_type,
-                                             "stuff", uintptr_type,
+                                             "offset", uint8_type,
+                                             "wrapped", bool_type,
+                                             "B", uint8_type,
+                                             "i", uint8_type,
                                              "bucket", uintptr_type,
                                              "checkBucket", uintptr_type);
   ret->set_is_struct_incomparable();
Index: gcc/go/gofrontend/types.h
===================================================================
--- gcc/go/gofrontend/types.h   (revision 256262)
+++ gcc/go/gofrontend/types.h   (working copy)
@@ -2826,6 +2826,9 @@ class Map_type : public Type
   static Type*
   make_map_type_descriptor_type();
 
+  // This must be in  sync with libgo/go/runtime/hashmap.go.
+  static const int bucket_size = 8;
+
  protected:
   int
   do_traverse(Traverse*);
@@ -2867,7 +2870,6 @@ class Map_type : public Type
 
  private:
   // These must be in sync with libgo/go/runtime/hashmap.go.
-  static const int bucket_size = 8;
   static const int max_key_size = 128;
   static const int max_val_size = 128;
   static const int max_zero_size = 1024;
Index: gcc/go/gofrontend/wb.cc
===================================================================
--- gcc/go/gofrontend/wb.cc     (revision 256262)
+++ gcc/go/gofrontend/wb.cc     (working copy)
@@ -331,6 +331,25 @@ Gogo::assign_needs_write_barrier(Express
   if (!lhs->type()->has_pointer())
     return false;
 
+  // An assignment to a field is handled like an assignment to the
+  // struct.
+  while (true)
+    {
+      // Nothing to do for a type that can not be in the heap, or a
+      // pointer to a type that can not be in the heap.  We check this
+      // at each level of a struct.
+      if (!lhs->type()->in_heap())
+       return false;
+      if (lhs->type()->points_to() != NULL
+         && !lhs->type()->points_to()->in_heap())
+       return false;
+
+      Field_reference_expression* fre = lhs->field_reference_expression();
+      if (fre == NULL)
+       break;
+      lhs = fre->expr();
+    }
+
   // Nothing to do for an assignment to a temporary.
   if (lhs->temporary_reference_expression() != NULL)
     return false;
@@ -359,12 +378,30 @@ Gogo::assign_needs_write_barrier(Express
        }
     }
 
-  // Nothing to do for a type that can not be in the heap, or a
-  // pointer to a type that can not be in the heap.
-  if (!lhs->type()->in_heap())
-    return false;
-  if (lhs->type()->points_to() != NULL && !lhs->type()->points_to()->in_heap())
-    return false;
+  // For a struct assignment, we don't need a write barrier if all the
+  // pointer types can not be in the heap.
+  Struct_type* st = lhs->type()->struct_type();
+  if (st != NULL)
+    {
+      bool in_heap = false;
+      const Struct_field_list* fields = st->fields();
+      for (Struct_field_list::const_iterator p = fields->begin();
+          p != fields->end();
+          p++)
+       {
+         Type* ft = p->type();
+         if (!ft->has_pointer())
+           continue;
+         if (!ft->in_heap())
+           continue;
+         if (ft->points_to() != NULL && !ft->points_to()->in_heap())
+           continue;
+         in_heap = true;
+         break;
+       }
+      if (!in_heap)
+       return false;
+    }
 
   // Write barrier needed in other cases.
   return true;
Index: libgo/MERGE
===================================================================
--- libgo/MERGE (revision 256262)
+++ libgo/MERGE (working copy)
@@ -1,4 +1,4 @@
-c8aec4095e089ff6ac50d18e97c3f46561f14f48
+9ce6b5c2ed5d3d5251b9a6a0c548d5fb2c8567e8
 
 The first line of this file holds the git revision number of the
 last merge done from the master library sources.
Index: libgo/Makefile.am
===================================================================
--- libgo/Makefile.am   (revision 256262)
+++ libgo/Makefile.am   (working copy)
@@ -400,8 +400,11 @@ toolexeclibgounicode_DATA = \
 # internal packages nothing will explicitly depend on them.
 # 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
+       net/internal/socktest.gox \
+       os/signal/internal/pty.gox
 
 if LIBGO_IS_RTEMS
 rtems_task_variable_add_file = runtime/rtems-task-variable-add.c
@@ -533,6 +536,24 @@ s-version: Makefile
        $(SHELL) $(srcdir)/mvifdiff.sh version.go.tmp version.go
        $(STAMP) $@
 
+objabi.go: s-objabi; @true
+s-objabi: Makefile
+       rm -f objabi.go.tmp
+       echo "package objabi" > objabi.go.tmp
+       echo "import \"runtime\"" >> objabi.go.tmp
+       echo 'const defaultGOROOT = `$(prefix)`' >> objabi.go.tmp
+       echo 'const defaultGO386 = `sse2`' >> objabi.go.tmp
+       echo 'const defaultGOARM = `5`' >> objabi.go.tmp
+       echo 'const defaultGOMIPS = `hardfloat`' >> objabi.go.tmp
+       echo 'const defaultGOOS = runtime.GOOS' >> objabi.go.tmp
+       echo 'const defaultGOARCH = runtime.GOARCH' >> objabi.go.tmp
+       echo 'const defaultGO_EXTLINK_ENABLED = ``' >> objabi.go.tmp
+       echo 'const version = `'`cat $(srcdir)/VERSION | sed 1q`' '`$(GOC) 
--version | sed 1q`'`' >> objabi.go.tmp
+       echo 'const stackGuardMultiplier = 1' >> objabi.go.tmp
+       echo 'const goexperiment = ``' >> objabi.go.tmp
+       $(SHELL) $(srcdir)/mvifdiff.sh objabi.go.tmp objabi.go
+       $(STAMP) $@
+
 runtime_sysinfo.go: s-runtime_sysinfo; @true
 s-runtime_sysinfo: $(srcdir)/mkrsysinfo.sh gen-sysinfo.go
        GOARCH=$(GOARCH) GOOS=$(GOOS) $(SHELL) $(srcdir)/mkrsysinfo.sh
@@ -553,10 +574,11 @@ zdefaultcc.go: s-zdefaultcc; @true
 s-zdefaultcc: Makefile
        echo 'package cfg' > zdefaultcc.go.tmp
        echo >> zdefaultcc.go.tmp
-       echo 'const DefaultGCCGO = "$(bindir)/$(GCCGO_INSTALL_NAME)"' >> 
zdefaultcc.go.tmp
-       echo 'const DefaultCC = "$(GCC_INSTALL_NAME)"' >> zdefaultcc.go.tmp
-       echo 'const DefaultCXX = "$(GXX_INSTALL_NAME)"' >> zdefaultcc.go.tmp
+       echo 'func DefaultGCCGO(goos, goarch string) string { return 
"$(bindir)/$(GCCGO_INSTALL_NAME)" }' >> zdefaultcc.go.tmp
+       echo 'func DefaultCC(goos, goarch string) string { return 
"$(GCC_INSTALL_NAME)" }' >> zdefaultcc.go.tmp
+       echo 'func DefaultCXX(goos, goarch string) string { return 
"$(GXX_INSTALL_NAME)" }' >> zdefaultcc.go.tmp
        echo 'const DefaultPkgConfig = "pkg-config"' >> zdefaultcc.go.tmp
+       echo 'var OSArchSupportsCgo = map[string]bool{}' >> zdefaultcc.go.tmp
        $(SHELL) $(srcdir)/../move-if-change zdefaultcc.go.tmp zdefaultcc.go
        $(STAMP) $@ 
 
@@ -758,11 +780,15 @@ PACKAGES = \
        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 \
@@ -824,6 +850,7 @@ PACKAGES = \
        os \
        os/exec \
        os/signal \
+       os/signal/internal/pty \
        os/user \
        path \
        path/filepath \
@@ -905,7 +932,7 @@ libgolibbegin_a_CFLAGS = $(AM_CFLAGS) -f
 GOTOOL_PACKAGES = \
        cmd/go/internal/base \
        cmd/go/internal/bug \
-       cmd/go/internal/buildid \
+       cmd/go/internal/cache \
        cmd/go/internal/cfg \
        cmd/go/internal/clean \
        cmd/go/internal/cmdflag \
@@ -927,7 +954,12 @@ GOTOOL_PACKAGES = \
        cmd/go/internal/web \
        cmd/go/internal/work \
        cmd/internal/browser \
-       cmd/internal/objabi
+       cmd/internal/buildid \
+       cmd/internal/edit \
+       cmd/internal/objabi \
+       cmd/internal/test2json \
+       cmd/vet/internal/cfg \
+       cmd/vet/internal/whitelist
 
 libgotool_a_SOURCES =
 libgotool_a_DEPENDENCIES = $(addsuffix .lo,$(GOTOOL_PACKAGES))
@@ -1136,17 +1168,23 @@ runtime_pprof_check_GOCFLAGS = -static-l
 extra_go_files_runtime_internal_sys = version.go
 runtime/internal/sys.lo.dep: $(extra_go_files_runtime_internal_sys)
 
+extra_go_files_cmd_internal_objabi = objabi.go
+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
 extra_check_libs_cmd_go_internal_load = $(abs_builddir)/libgotool.a
 extra_check_libs_cmd_go_internal_work = $(abs_builddir)/libgotool.a
 
+extra_check_libs_cmd_vet_internal_cfg = $(abs_builddir)/libgotool.a
+
 # FIXME: The following C files may as well move to the runtime
 # directory and be treated like other C files.
 
@@ -1233,10 +1271,12 @@ 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 \
@@ -1258,11 +1298,16 @@ TEST_PACKAGES = \
        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 \
@@ -1315,6 +1360,7 @@ TEST_PACKAGES = \
        go/constant/check \
        go/doc/check \
        go/format/check \
+       go/importer/check \
        go/internal/gcimporter/check \
        go/internal/gccgoimporter/check \
        go/internal/srcimporter/check \
@@ -1325,6 +1371,7 @@ TEST_PACKAGES = \
        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 \
Index: libgo/VERSION
===================================================================
--- libgo/VERSION       (revision 256262)
+++ libgo/VERSION       (working copy)
@@ -1 +1 @@
-go1.9
+go1.10beta1
Index: libgo/configure.ac
===================================================================
--- libgo/configure.ac  (revision 256306)
+++ libgo/configure.ac  (working copy)
@@ -11,7 +11,7 @@ AC_INIT(package-unused, version-unused,,
 AC_CONFIG_SRCDIR(Makefile.am)
 AC_CONFIG_HEADER(config.h)
 
-libtool_VERSION=12:0:0
+libtool_VERSION=13:0:0
 AC_SUBST(libtool_VERSION)
 
 AM_ENABLE_MULTILIB(, ..)
@@ -215,7 +215,7 @@ ALLGOARCHFAMILY="I386 ALPHA AMD64 ARM AR
 
 GOARCH=unknown
 GOARCH_FAMILY=unknown
-GOARCH_BIGENDIAN=0
+GOARCH_BIGENDIAN=false
 GOARCH_CACHELINESIZE=64
 GOARCH_PHYSPAGESIZE=4096
 GOARCH_PCQUANTUM=1
@@ -243,6 +243,12 @@ case ${host} in
     GOARCH_CACHELINESIZE=32
     GOARCH_PCQUANTUM=4
     GOARCH_MINFRAMESIZE=4
+    case ${host} in
+      arm*b*-*-*)
+       GOARCH=armbe
+        GOARCH_BIGENDIAN=true
+       ;;
+    esac
     ;;
 changequote(,)dnl
   i[34567]86-*-* | x86_64-*-*)
@@ -270,7 +276,7 @@ GOARCH_HUGEPAGESIZE="1 << 21"
   m68k*-*-*)
     GOARCH=m68k
     GOARCH_FAMILY=M68K
-    GOARCH_BIGENDIAN=1
+    GOARCH_BIGENDIAN=true
     GOARCH_CACHELINESIZE=16
     GOARCH_PCQUANTUM=4
     GOARCH_INT64ALIGN=2
@@ -313,7 +319,7 @@ GOARCH_HUGEPAGESIZE="1 << 21"
         GOARCH="${GOARCH}le"
         ;;
     *)
-       GOARCH_BIGENDIAN=1
+       GOARCH_BIGENDIAN=true
         ;;
     esac
     GOARCH_CACHELINESIZE=32
@@ -327,7 +333,7 @@ GOARCH_HUGEPAGESIZE="1 << 21"
 #endif],
 [GOARCH=ppc
 GOARCH_FAMILY=PPC
-GOARCH_BIGENDIAN=1
+GOARCH_BIGENDIAN=true
 ],
     [
 GOARCH_FAMILY=PPC64
@@ -338,7 +344,7 @@ AC_COMPILE_IFELSE([
 [GOARCH=ppc64le
 ],
 [GOARCH=ppc64
-GOARCH_BIGENDIAN=1
+GOARCH_BIGENDIAN=true
 ])])
     GOARCH_PHYSPAGESIZE=65536
     GOARCH_PCQUANTUM=4
@@ -356,7 +362,7 @@ GOARCH_MINFRAMESIZE=4
 GOARCH_FAMILY=S390X
 GOARCH_MINFRAMESIZE=8
 ])
-    GOARCH_BIGENDIAN=1
+    GOARCH_BIGENDIAN=true
     GOARCH_CACHELINESIZE=256
     GOARCH_PCQUANTUM=2
     ;;
@@ -371,7 +377,7 @@ GOARCH_FAMILY=SPARC
 [GOARCH=sparc64
 GOARCH_FAMILY=SPARC64
 ])
-    GOARCH_BIGENDIAN=1
+    GOARCH_BIGENDIAN=true
     GOARCH_PHYSPAGESIZE=8192
     GOARCH_PCQUANTUM=4
     ;;
@@ -718,7 +724,7 @@ AC_COMPILE_IFELSE([int i;],
 CFLAGS=$CFLAGS_hold])
 MATH_FLAG=
 if test "$libgo_cv_c_fancymath" = yes; then
-  MATH_FLAG="-mfancy-math-387 -funsafe-math-optimizations"
+  MATH_FLAG="-mfancy-math-387 -funsafe-math-optimizations -fno-math-errno"
 else
   MATH_FLAG="-ffp-contract=off"
 fi
Index: libgo/runtime/go-callers.c
===================================================================
--- libgo/runtime/go-callers.c  (revision 256262)
+++ libgo/runtime/go-callers.c  (working copy)
@@ -127,8 +127,12 @@ callback (void *data, uintptr_t pc, cons
            p = filename;
          if (__builtin_strcmp (p, "/proc.c") == 0)
            {
-             if (__builtin_strcmp (function, "kickoff") == 0
-                 || __builtin_strcmp (function, "runtime.mstart") == 0
+             if (__builtin_strcmp (function, "runtime_mstart") == 0)
+               return 1;
+           }
+         else if (__builtin_strcmp (p, "/proc.go") == 0)
+           {
+             if (__builtin_strcmp (function, "runtime.kickoff") == 0
                  || __builtin_strcmp (function, "runtime.main") == 0)
                return 1;
            }
@@ -184,6 +188,21 @@ runtime_callers (int32 skip, Location *l
   backtrace_full (__go_get_backtrace_state (), 0, callback, error_callback,
                  &data);
   runtime_xadd (&runtime_in_callers, -1);
+
+  /* For some reason GCC sometimes loses the name of a thunk function
+     at the top of the stack.  If we are skipping thunks, skip that
+     one too.  */
+  if (!keep_thunks
+      && data.index > 2
+      && locbuf[data.index - 2].function.len == 0
+      && locbuf[data.index - 1].function.str != NULL
+      && __builtin_strcmp ((const char *) locbuf[data.index - 1].function.str,
+                          "runtime.kickoff") == 0)
+    {
+      locbuf[data.index - 2] = locbuf[data.index - 1];
+      --data.index;
+    }
+
   return data.index;
 }
 
Index: libgo/runtime/proc.c
===================================================================
--- libgo/runtime/proc.c        (revision 256262)
+++ libgo/runtime/proc.c        (working copy)
@@ -32,6 +32,8 @@ extern void *__splitstack_makecontext(si
 
 extern void * __splitstack_resetcontext(void *context[10], size_t *);
 
+extern void __splitstack_releasecontext(void *context[10]);
+
 extern void *__splitstack_find(void *, void *, size_t *, void **, void **,
                               void **);
 
@@ -269,6 +271,9 @@ runtime_newosproc(M *mp)
                runtime_printf("pthread_create failed: %d\n", ret);
                runtime_throw("pthread_create");
        }
+
+       if(pthread_attr_destroy(&attr) != 0)
+               runtime_throw("pthread_attr_destroy");
 }
 
 // Switch context to a different goroutine.  This is like longjmp.
@@ -377,10 +382,12 @@ extern void kickoff(void)
   __asm__(GOSYM_PREFIX "runtime.kickoff");
 extern void minit(void)
   __asm__(GOSYM_PREFIX "runtime.minit");
-extern void mstart1(void)
+extern void mstart1(int32)
   __asm__(GOSYM_PREFIX "runtime.mstart1");
 extern void stopm(void)
   __asm__(GOSYM_PREFIX "runtime.stopm");
+extern void mexit(bool)
+  __asm__(GOSYM_PREFIX "runtime.mexit");
 extern void handoffp(P*)
   __asm__(GOSYM_PREFIX "runtime.handoffp");
 extern void wakep(void)
@@ -519,6 +526,11 @@ runtime_mstart(void *arg)
                *(int*)0x21 = 0x21;
        }
 
+       if(mp->exiting) {
+               mexit(true);
+               return nil;
+       }
+
        // Initial call to getcontext--starting thread.
 
 #ifdef USING_SPLIT_STACK
@@ -528,7 +540,7 @@ runtime_mstart(void *arg)
        }
 #endif
 
-       mstart1();
+       mstart1(0);
 
        // mstart1 does not return, but we need a return statement
        // here to avoid a compiler warning.
@@ -751,6 +763,30 @@ runtime_malg(bool allocatestack, bool si
        return newg;
 }
 
+void stackfree(G*)
+  __asm__(GOSYM_PREFIX "runtime.stackfree");
+
+// stackfree frees the stack of a g.
+void
+stackfree(G* gp)
+{
+#if USING_SPLIT_STACK
+  __splitstack_releasecontext((void*)(&gp->stackcontext[0]));
+#else
+  // If gcstacksize is 0, the stack is allocated by libc and will be
+  // released when the thread exits. Otherwise, in 64-bit mode it was
+  // allocated using sysAlloc and in 32-bit mode it was allocated
+  // using garbage collected memory.
+  if (gp->gcstacksize != 0) {
+    if (sizeof(void*) == 8) {
+      runtime_sysFree(gp->gcinitialsp, gp->gcstacksize, 
&getMemstats()->stacks_sys);
+    }
+    gp->gcinitialsp = nil;
+    gp->gcstacksize = 0;
+  }
+#endif
+}
+
 void resetNewG(G*, void **, uintptr*)
   __asm__(GOSYM_PREFIX "runtime.resetNewG");
 
Index: libgo/runtime/runtime.h
===================================================================
--- libgo/runtime/runtime.h     (revision 256262)
+++ libgo/runtime/runtime.h     (working copy)
@@ -265,11 +265,12 @@ void*     runtime_mallocgc(uintptr, const Ty
   __asm__ (GOSYM_PREFIX "runtime.mallocgc");
 void*  runtime_sysAlloc(uintptr, uint64*)
   __asm__ (GOSYM_PREFIX "runtime.sysAlloc");
+void   runtime_sysFree(void*, uintptr, uint64*)
+  __asm__ (GOSYM_PREFIX "runtime.sysFree");
 void   runtime_mprofinit(void);
 #define runtime_getcallersp(p) __builtin_frame_address(0)
 void   runtime_mcall(FuncVal*)
   __asm__ (GOSYM_PREFIX "runtime.mcall");
-uint32 runtime_fastrand(void) __asm__ (GOSYM_PREFIX "runtime.fastrand");
 int32  runtime_timediv(int64, int32, int32*)
   __asm__ (GOSYM_PREFIX "runtime.timediv");
 int32  runtime_round2(int32 x); // round x up to a power of 2.
Index: libgo/runtime/runtime_c.c
===================================================================
--- libgo/runtime/runtime_c.c   (revision 256262)
+++ libgo/runtime/runtime_c.c   (working copy)
@@ -33,21 +33,6 @@ runtime_atoi(const byte *p, intgo len)
        return n;
 }
 
-uint32
-runtime_fastrand(void)
-{
-       M *m;
-       uint32 x;
-
-       m = runtime_m();
-       x = m->fastrand;
-       x += x;
-       if(x & 0x80000000L)
-               x ^= 0x88888eefUL;
-       m->fastrand = x;
-       return x;
-}
-
 int64
 runtime_cputicks(void)
 {
Index: libgo/testsuite/gotest
===================================================================
--- libgo/testsuite/gotest      (revision 256262)
+++ libgo/testsuite/gotest      (working copy)
@@ -510,7 +510,7 @@ localname() {
        ppc64*) text="[TD]" ;;
        esac
 
-       symtogo='sed -e s/_test/XXXtest/ -e s/.*_\([^_]*\.\)/\1/ -e 
s/XXXtest/_test/'
+       symtogo='sed -e s/_test\([^A-Za-z0-9]\)/XXXtest\1/ -e 
s/.*_\([^_]*\.\)/\1/ -e s/XXXtest/_test/'
 
        # test functions are named TestFoo
        # the grep -v eliminates methods and other special names
Index: libgo/go/runtime/cgo_gccgo.go
===================================================================
--- libgo/go/runtime/cgo_gccgo.go       (revision 256262)
+++ libgo/go/runtime/cgo_gccgo.go       (working copy)
@@ -27,6 +27,13 @@ var iscgo bool
 // The extra M must be created before any C/C++ code calls cgocallback.
 var cgoHasExtraM bool
 
+// cgoAlwaysFalse is a boolean value that is always false.
+// The cgo-generated code says if cgoAlwaysFalse { cgoUse(p) }.
+// The compiler cannot see that cgoAlwaysFalse is always false,
+// so it emits the test and keeps the call, giving the desired
+// escape analysis result. The test is cheaper than the call.
+var cgoAlwaysFalse bool
+
 // Cgocall prepares to call from code written in Go to code written in
 // C/C++. This takes the current goroutine out of the Go scheduler, as
 // though it were making a system call. Otherwise the program can
@@ -37,12 +44,11 @@ var cgoHasExtraM bool
 //     defer syscall.Cgocalldone()
 //     cfunction()
 func Cgocall() {
-       lockOSThread()
        mp := getg().m
        mp.ncgocall++
        mp.ncgo++
-       mp.incgo = true
        entersyscall(0)
+       mp.incgo = true
 }
 
 // CgocallDone prepares to return to Go code from C/C++ code.
@@ -59,8 +65,6 @@ func CgocallDone() {
        if readgstatus(gp)&^_Gscan == _Gsyscall {
                exitsyscall(0)
        }
-
-       unlockOSThread()
 }
 
 // CgocallBack is used when calling from C/C++ code into Go code.
@@ -78,6 +82,8 @@ func CgocallBack() {
                mp.dropextram = true
        }
 
+       lockOSThread()
+
        exitsyscall(0)
        gp.m.incgo = false
 
@@ -100,6 +106,8 @@ func CgocallBack() {
 // CgocallBackDone prepares to return to C/C++ code that has called
 // into Go code.
 func CgocallBackDone() {
+       unlockOSThread()
+
        // If we are the top level Go function called from C/C++, then
        // we need to release the m. But don't release it if we are
        // panicing; since this is the top level, we are going to
Index: libgo/go/runtime/mem_gccgo.go
===================================================================
--- libgo/go/runtime/mem_gccgo.go       (revision 256262)
+++ libgo/go/runtime/mem_gccgo.go       (working copy)
@@ -13,9 +13,10 @@ import (
 
 // Functions called by C code.
 //go:linkname sysAlloc runtime.sysAlloc
+//go:linkname sysFree runtime.sysFree
 
 //extern mmap
-func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uintptr) 
unsafe.Pointer
+func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off 
uintptr) unsafe.Pointer
 
 //extern munmap
 func munmap(addr unsafe.Pointer, length uintptr) int32
@@ -40,6 +41,14 @@ func init() {
        }
 }
 
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uintptr) 
(unsafe.Pointer, int) {
+       p := sysMmap(addr, n, prot, flags, fd, off)
+       if uintptr(p) == _MAP_FAILED {
+               return nil, errno()
+       }
+       return p, 0
+}
+
 // NOTE: vec must be just 1 byte long here.
 // Mincore returns ENOMEM if any of the pages are unmapped,
 // but we want to know that all of the pages are unmapped.
@@ -75,31 +84,30 @@ func addrspace_free(v unsafe.Pointer, n
        return true
 }
 
-func mmap_fixed(v unsafe.Pointer, n uintptr, prot, flags, fd int32, offset 
uintptr) unsafe.Pointer {
-       p := mmap(v, n, prot, flags, fd, offset)
+func mmap_fixed(v unsafe.Pointer, n uintptr, prot, flags, fd int32, offset 
uintptr) (unsafe.Pointer, int) {
+       p, err := mmap(v, n, prot, flags, fd, offset)
        // On some systems, mmap ignores v without
        // MAP_FIXED, so retry if the address space is free.
        if p != v && addrspace_free(v, n) {
-               if uintptr(p) != _MAP_FAILED {
+               if err == 0 {
                        munmap(p, n)
                }
-               p = mmap(v, n, prot, flags|_MAP_FIXED, fd, offset)
+               p, err = mmap(v, n, prot, flags|_MAP_FIXED, fd, offset)
        }
-       return p
+       return p, err
 }
 
 // Don't split the stack as this method may be invoked without a valid G, which
 // prevents us from allocating more stack.
 //go:nosplit
 func sysAlloc(n uintptr, sysStat *uint64) unsafe.Pointer {
-       p := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, 
mmapFD, 0)
-       if uintptr(p) == _MAP_FAILED {
-               errval := errno()
-               if errval == _EACCES {
+       p, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, 
mmapFD, 0)
+       if err != 0 {
+               if err == _EACCES {
                        print("runtime: mmap: access denied\n")
                        exit(2)
                }
-               if errval == _EAGAIN {
+               if err == _EAGAIN {
                        print("runtime: mmap: too much locked memory (check 
'ulimit -l').\n")
                        exit(2)
                }
@@ -225,9 +233,9 @@ func sysReserve(v unsafe.Pointer, n uint
        // if we can reserve at least 64K and check the assumption in SysMap.
        // Only user-mode Linux (UML) rejects these requests.
        if sys.PtrSize == 8 && uint64(n) > 1<<32 {
-               p := mmap_fixed(v, 64<<10, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, 
mmapFD, 0)
-               if p != v {
-                       if uintptr(p) != _MAP_FAILED {
+               p, err := mmap_fixed(v, 64<<10, _PROT_NONE, 
_MAP_ANON|_MAP_PRIVATE, mmapFD, 0)
+               if p != v || err != 0 {
+                       if err == 0 {
                                munmap(p, 64<<10)
                        }
                        return nil
@@ -237,8 +245,8 @@ func sysReserve(v unsafe.Pointer, n uint
                return v
        }
 
-       p := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, mmapFD, 0)
-       if uintptr(p) == _MAP_FAILED {
+       p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, mmapFD, 0)
+       if err != 0 {
                return nil
        }
        *reserved = true
@@ -259,12 +267,12 @@ func sysMap(v unsafe.Pointer, n uintptr,
                        // to do this - we do not on other platforms.
                        flags |= _MAP_FIXED
                }
-               p := mmap_fixed(v, n, _PROT_READ|_PROT_WRITE, flags, mmapFD, 0)
-               if uintptr(p) == _MAP_FAILED && errno() == _ENOMEM {
+               p, err := mmap_fixed(v, n, _PROT_READ|_PROT_WRITE, flags, 
mmapFD, 0)
+               if err == _ENOMEM {
                        throw("runtime: out of memory")
                }
-               if p != v {
-                       print("runtime: address space conflict: map(", v, ") = 
", p, "\n")
+               if p != v || err != 0 {
+                       print("runtime: address space conflict: map(", v, ") = 
", p, " (err ", err, ")\n")
                        throw("runtime: address space conflict")
                }
                return
@@ -275,11 +283,11 @@ func sysMap(v unsafe.Pointer, n uintptr,
                // So always unmap first even if it is already unmapped.
                munmap(v, n)
        }
-       p := mmap(v, n, _PROT_READ|_PROT_WRITE, 
_MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, mmapFD, 0)
-       if uintptr(p) == _MAP_FAILED && errno() == _ENOMEM {
+       p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, 
_MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, mmapFD, 0)
+       if err == _ENOMEM {
                throw("runtime: out of memory")
        }
-       if p != v {
+       if p != v || err != 0 {
                throw("runtime: cannot map pages in arena address space")
        }
 }
Index: libgo/go/runtime/mgc_gccgo.go
===================================================================
--- libgo/go/runtime/mgc_gccgo.go       (revision 256262)
+++ libgo/go/runtime/mgc_gccgo.go       (working copy)
@@ -6,7 +6,10 @@
 
 package runtime
 
-import "unsafe"
+import (
+       "runtime/internal/sys"
+       "unsafe"
+)
 
 // gcRoot is a single GC root: a variable plus a ptrmask.
 type gcRoot struct {
@@ -85,3 +88,21 @@ func checkPreempt() {
        gp.scanningself = false
        mcall(gopreempt_m)
 }
+
+// gcWriteBarrier implements a write barrier. This is implemented in
+// assembly in the gc library, but there is no special advantage to
+// doing so with gccgo.
+//go:nosplit
+//go:nowritebarrier
+func gcWriteBarrier(dst *uintptr, src uintptr) {
+       buf := &getg().m.p.ptr().wbBuf
+       next := buf.next
+       np := next + 2*sys.PtrSize
+       buf.next = np
+       *(*uintptr)(unsafe.Pointer(next)) = src
+       *(*uintptr)(unsafe.Pointer(next + sys.PtrSize)) = *dst
+       if np >= buf.end {
+               wbBufFlush(dst, src)
+       }
+       *dst = src
+}
Index: libgo/go/runtime/signal_gccgo.go
===================================================================
--- libgo/go/runtime/signal_gccgo.go    (revision 256262)
+++ libgo/go/runtime/signal_gccgo.go    (working copy)
@@ -46,11 +46,6 @@ func kill(pid _pid_t, sig uint32) int32
 //extern setitimer
 func setitimer(which int32, new *_itimerval, old *_itimerval) int32
 
-type sigTabT struct {
-       flags int32
-       name  string
-}
-
 type sigctxt struct {
        info *_siginfo_t
        ctxt unsafe.Pointer
Index: libgo/go/runtime/traceback_gccgo.go
===================================================================
--- libgo/go/runtime/traceback_gccgo.go (revision 256262)
+++ libgo/go/runtime/traceback_gccgo.go (working copy)
@@ -52,7 +52,7 @@ func c_callers(skip int32, locbuf *locat
 // callers returns a stack trace of the current goroutine.
 // The gc version of callers takes []uintptr, but we take []location.
 func callers(skip int, locbuf []location) int {
-       n := c_callers(int32(skip), &locbuf[0], int32(len(locbuf)), false)
+       n := c_callers(int32(skip)+1, &locbuf[0], int32(len(locbuf)), false)
        return int(n)
 }
 
@@ -156,7 +156,7 @@ func goroutineheader(gp *g) {
        if waitfor >= 1 {
                print(", ", waitfor, " minutes")
        }
-       if gp.lockedm != nil {
+       if gp.lockedm != 0 {
                print(", locked to thread")
        }
        print("]:\n")

Reply via email to