diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 47dd5fbb9083fcf76b6a3dac040b21f5cbed69d0..ce10ee1d8d466b160c2646af2b8a1c39a59d5045 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-8505defaa91ecc5b42afd02eb335981e8b02b288
+d5d00d310ec33aeb18f33f807956ec0c4eeea6bb
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/cmd/go/internal/work/gccgo.go b/libgo/go/cmd/go/internal/work/gccgo.go
index f6fa17da85cfd2720a382ebb53339914d6342411..63d5c624f79c5989cfde098a8ad67283282e3e5d 100644
--- a/libgo/go/cmd/go/internal/work/gccgo.go
+++ b/libgo/go/cmd/go/internal/work/gccgo.go
@@ -596,14 +596,28 @@ func gccgoPkgpath(p *load.Package) string {
 	return p.ImportPath
 }
 
+// gccgoCleanPkgpath returns the form of p's pkgpath that gccgo uses
+// for symbol names. This is like gccgoPkgpathToSymbolNew in cmd/cgo/out.go.
 func gccgoCleanPkgpath(p *load.Package) string {
-	clean := func(r rune) rune {
+	ppath := gccgoPkgpath(p)
+	bsl := []byte{}
+	changed := false
+	for _, c := range []byte(ppath) {
 		switch {
-		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
-			'0' <= r && r <= '9':
-			return r
+		case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z',
+			'0' <= c && c <= '9', c == '_':
+			bsl = append(bsl, c)
+		case c == '.':
+			bsl = append(bsl, ".x2e"...)
+			changed = true
+		default:
+			encbytes := []byte(fmt.Sprintf("..z%02x", c))
+			bsl = append(bsl, encbytes...)
+			changed = true
 		}
-		return '_'
 	}
-	return strings.Map(clean, gccgoPkgpath(p))
+	if !changed {
+		return ppath
+	}
+	return string(bsl)
 }