-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Description
What version of Go are you using (go version
)?
$ go version tip
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/home/xiaji01/.cache/go-build"
GOENV="/home/xiaji01/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/xiaji01/.go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/xiaji01/.go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/xiaji01/util/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/xiaji01/util/go/pkg/tool/linux_arm64"
GCCGO="gccgo"
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 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build044102122=/tmp/go-build -gno-record-gcc-switches"
What did you do?
GCC-9.4 introduced the outline atomics support for arm64 and the feature was made default since GCC-10.1. Go's internal linking mode doesn't work well with the feature, here is what have been spotted so far and a sample case, further analysis is ongoing.
With GCC-10.1 and default CGO flags, or GCC-9.4+with an additional "-moutline-atomics" flag, the sample case runs into a link issue with '-linkmode=internal', internal linking tries to resolve undefined external references in libgcc.a, while the problematic variable __aarch64_have_lse_atomic and its init function don't get resolved.
$ go build -ldflags='-linkmode=internal'
libgcc(.text): unknown symbol __aarch64_have_lse_atomics
lse.c
int test_cas_atomic_int (int *ptr, int *expected, int desired)
{
return __atomic_compare_exchange_n (ptr, expected, desired, 0, 0, 0);
}
mult.c
#include <stdlib.h>
#include <stdio.h>
extern int test_cas_atomic_int (int *ptr, int *expected, int desired);
int test_cgo(int a, int b) {
int old = a;
int new = b;
printf("before: old = %d, new = %d\n", old, new);
test_cas_atomic_int(&old, &old, new);
printf("after: old = %d, new = %d\n", old, new);
return new * old + old;
}
mult.go
package main
/*
extern int test_cgo(int a, int b);
*/
import "C"
import (
"fmt"
)
func main() {
a := 3
b := 5
c := C.test_cgo(C.int(a), C.int(b))
fmt.Println("test_cgo:", int(c))
}
What did you expect to see?
Trying to apply GCC-10 and its new LSE features to CGO part, expect they work smoothly.
What did you see instead?
Internal linking doesn't work.