Repository: go
Issue: cmd/dist: GOHOSTARCH defaults to kernel arch even when it does not match userspace arch
Labels: NeedsInvestigation,GoCommand

### What version of Go are you using (`go version`)?

<pre>
$ go version
go version go1.15.15 linux/arm
</pre>

### Does this issue reproduce with the latest release?

Yes

### What operating system and processor architecture are you using (`go env`)?

<details><summary><code>go env</code> Output</summary><br><pre>
$ go env
GO111MODULE=""
GOARCH="arm"
GOBIN=""
GOCACHE="/home/jeff/.cache/go-build"
GOENV="/home/jeff/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="arm"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/jeff/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/jeff/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go-1.15"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go-1.15/pkg/tool/linux_arm"
GCCGO="gccgo"
GOARM="6"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -marm -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build431512454=/tmp/go-build -gno-record-gcc-switches"
</pre></details>

### What did you do?

This was first raised in https://github.com/openwrt/packages/pull/18584.

With Raspbian / Raspberry Pi OS and later models of Raspberry Pi, it is possible to boot a 64-bit kernel with an otherwise completely 32-bit userland (by setting [`arm_64bit=1`](https://www.raspberrypi.com/documentation/computers/config_txt.html#arm_64bit) in config.txt).

I have replicated this setup with a Raspberry Pi 3 Model B and Raspberry Pi OS Lite (32-bit, based on Debian 11 bullseye):

```
$ uname -a
Linux raspberrypi 5.15.32-v8+ #1538 SMP PREEMPT Thu Mar 31 19:40:39 BST 2022 aarch64 GNU/Linux
```

And I am trying to compile the latest release of Go (1.18.2) using the distro packaged Go (1.15.15) as bootstrap.

### What did you expect to see?

Go compiled with no extra flags/environment variables needed.

### What did you see instead?

A build error always occurs:

```
$ ./make.bash
Building Go cmd/dist using /usr/lib/go-1.15. (go1.15.15 linux/arm)
Building Go toolchain1 using /usr/lib/go-1.15.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
Building Go toolchain2 using go_bootstrap and Go toolchain1.
Building Go toolchain3 using go_bootstrap and Go toolchain2.
Building packages and commands for linux/arm64.
# runtime/cgo
In file included from _cgo_export.c:4:
cgo-gcc-export-header-prolog:25:14: error: size of array '_check_for_64_bit_pointer_matching_GoInt' is negative
go tool dist: FAILED: /media/Downloads/go/pkg/tool/linux_arm64/go_bootstrap install -gcflags=all= -ldflags=all= std cmd: exit status 2
```

Compilation continues for a while after the runtime/cgo error; it does not appear to be the direct cause of the `go tool dist` error.

(I have also seen compilation exit earlier due to an error occurring at the `Building Go toolchain3 using go_bootstrap and Go toolchain2.` stage, though I have not been able to replicate this consistently and am not certain it is related to this issue.)

This error appears to be caused by `GOHOSTARCH` defaulting to `arm64` (based on the output of `uname -m`) even though the userspace is 32-bit only. If I set `GOHOSTARCH=arm`, then compilation succeeds.

From the [installation documentation](https://go.dev/doc/install/source#environment) it appears that explicitly setting `GOHOSTARCH` is probably necessary/correct, but I wonder: why base `GOHOSTARCH` on the kernel arch when `GOHOSTARCH` from bootstrap Go appears to be a safer default value?