go: cmd/link: relocation addend overflows on darwin/arm64

Apologies if it’s too early to be filing bugs around darwin/arm64 or if this is already known.

What version of Go are you using (go version)?

% go version
go version devel +0dcc7d6ea8 Fri Nov 20 02:27:53 2020 +0000 darwin/arm64

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/shoenig/Library/Caches/go-build"
GOENV="/Users/shoenig/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/shoenig/Documents/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/shoenig/Documents/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/opt/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/go/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="devel +0dcc7d6ea8 Fri Nov 20 02:27:53 2020 +0000"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/dm/ywmn1y2n5sd5s47l80td5n140000gn/T/go-build981747890=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Built Go following https://github.com/golang/go/issues/38485#issuecomment-730247329

Build nomad f-darwin-arm64 branch

Run nomad version

What did you expect to see?

Version output

What did you see instead?

runtime: out of memory: cannot allocate 1729382219220254720-byte block (0 in use)
fatal error: out of memory

runtime stack:
runtime.throw(0x1016921a2, 0xd)
	runtime/panic.go:1112 +0x54 fp=0x16fc63730 sp=0x16fc63700 pc=0x1001d2f84
runtime.(*mcache).allocLarge(0x1039b0108, 0x17fffff7394083e0, 0x1, 0xfffffe730b194fe5)
	runtime/mcache.go:226 +0x2f0 fp=0x16fc637a0 sp=0x16fc63730 pc=0x1001b53c0
runtime.mallocgc(0x17fffff7394083e0, 0x101201800, 0x16fc63801, 0x1001f2ec4)
	runtime/malloc.go:1078 +0x82c fp=0x16fc63850 sp=0x16fc637a0 pc=0x1001ab94c
runtime.newobject(0x101201800, 0x10315a320)
	runtime/malloc.go:1177 +0x38 fp=0x16fc63880 sp=0x16fc63850 pc=0x1001abae8
runtime.malg(0x100008000, 0x1022359c8)
	runtime/proc.go:3870 +0x2c fp=0x16fc638d0 sp=0x16fc63880 pc=0x1001dde5c
runtime.mpreinit(0x10315a320)
	runtime/os_darwin.go:284 +0x28 fp=0x16fc638f0 sp=0x16fc638d0 pc=0x1001d0098
runtime.mcommoninit(0x10315a320, 0xffffffffffffffff)
	runtime/proc.go:708 +0xdc fp=0x16fc63940 sp=0x16fc638f0 pc=0x1001d69ec
runtime.schedinit()
	runtime/proc.go:601 +0x98 fp=0x16fc639a0 sp=0x16fc63940 pc=0x1001d6548
runtime.rt0_go(0x0, 0x0, 0x0, 0x0, 0x10019c000, 0x2, 0x16fc63b68, 0x16fc63b6e, 0x0, 0x16fc63b76, ...)
	runtime/asm_arm64.s:82 +0xd0 fp=0x16fc639d0 sp=0x16fc639a0 pc=0x100207f30

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 15 (13 by maintainers)

Commits related to this issue

Most upvoted comments

I think I understand it now. In runtime.malg we take the address of the type descriptor of the g struct (in order to allocate a g). As we combine all type descriptors into a single symbol typerel.*, we generate a relocation that targets typerel.* + offset. This binary is quite large and have a lot of types, so the offset is also quite large (0x80a45f in my case). On Mach-O ARM64, the relocation offset is a signed 24-bit value, and our offset overflows.

Not sure what the best solution is. Maybe we should not create such big symbols when combining type symbols (and other “grouped” symbols). That would need a non-trivial amount of work, though.

It’s hashicorp’s nomad

Looks like this may be specific to cgo, if I set CGO_ENABLED=0 the binary is able to build and run.

I don’t believe we deliberately allocate 1729382219220254720 bytes; this program compiles and runs with cgo enabled on all the major platforms.