Skip to content

cmd/link: missing CGO symbols in .dynsym on Go >= 1.21 on arm64 #62520

@mtardy

Description

@mtardy

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

$ go version
go version go1.21.1 linux/arm64

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/mahe.linux/.cache/go-build'
GOENV='/home/mahe.linux/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/mahe.linux/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/mahe.linux/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_arm64'
GOVCS=''
GOVERSION='go1.21.1'
GCCGO='gccgo'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1359563043=/tmp/go-build -gno-record-gcc-switches'

What did you do?

So the issue is a difference of behavior from Go 1.20 to Go 1.21 on arm64 (and not on amd64).

Let's make a minimal reproducing setup:

  1. Put that in a file, for example main.go and go build main.

    //go:build linux
    // +build linux
    
    package main
    
    /*
    int symbol_test(void)
    {
            return 0;
    }
    */
    import "C"
    
    func main() {
            C.symbol_test()
    }
  2. Use a binary to read the symbols, for example readelf -s main | grep symbol_test, you can use less as well to see:

    • With Go 1.20.8 (and before), there is a symbol_test in .dynsym and symbol_test in .symtab.
    • With Go 1.21.0 and 1.21.1, there is only a symbol_test in .symtab, it was removed from .dynsym.

So I cloned Go and did a git bissect to see which commit was the culprit and found that it was 1f29f39 -> https://go-review.googlesource.com/c/go/+/414654. Unfortunately, I lack context and understanding of the Go codebase to understand why this changed the behavior like that on arm64 specifically and if this is unintended.

For context, I was using uprobes on a Go binary, and for a reason that is not entirely clear for now, the lib I was using to load the probe is only reading .dynsym.

What did you expect to see?

I expected this behavior not to change, and especially not to change only on arm64 while amd64 is still behaving the same as in the past.

What did you see instead?

I saw that the symbol was missing in .dynsym using Go >= 1.21.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.WaitingForInfoIssue is not actionable because of missing required information, which needs to be provided.compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions