Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/link: Link bug on darwin arm64 #53495

Closed
578559967 opened this issue Jun 22, 2022 · 15 comments
Closed

cmd/link: Link bug on darwin arm64 #53495

578559967 opened this issue Jun 22, 2022 · 15 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@578559967
Copy link

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

$ go version
go version go1.18.3 darwin/arm64

Does this issue reproduce with the latest release?

Yes, it can reproduce with 1.17.5、1.17.6、1.17.10、1.18.1、1.18.2、1.18.3.

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

go env Output
$ go env
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/r/Library/Caches/go-build"
GOENV="/Users/r/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/r/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/r/go"
GOPRIVATE=""
GOPROXY="https://goproxy.cn,direct"
GOROOT="/Users/r/workspace/testgo/go1.18.3/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/r/workspace/testgo/go1.18.3/go/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.18.3"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/r/workspace/testcode/testassert/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/9k/p8mmy7xs2p71m74wg554rsvw0000gn/T/go-build954074863=/tmp/go-build -gno-record-gcc-switches -fno-common"
GOROOT/bin/go version: go version go1.18.3 darwin/arm64
GOROOT/bin/go tool compile -V: compile version go1.18.3
uname -v: Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:41 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T6000
ProductName:	macOS
ProductVersion:	12.1
BuildVersion:	21C52
lldb --version: lldb-1316.0.9.46
Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12)

What did you do?

test_1.18.go.tar.gz
Download the attachment, then run it with go 1.18 or 1.18.1 or 1.18.2 or 1.18.3.

tar zxvf ../test_1.18.go.tar.gz
go run ./test_1.18.go

What did you expect to see?

Expect to output:

ok

What did you see instead?

Output:

Field name not right:  92292 rstuvwxyz91869a91870abcdefghijklmnopqrstuvwxyz91870a91871abcdefghijklmnopqrstuvwxyz91871a91872abcdefghij

For lower versions of go, use these attachments instead:
test_1.17.10.go.tar.gz
test_1.17.6.go.tar.gz

This bug only happens on mac with arm64. Other platforms work fine.

@ianlancetaylor
Copy link
Contributor

CC @randall77 @cherrymui

@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jun 22, 2022
@ianlancetaylor ianlancetaylor added this to the Go1.20 milestone Jun 22, 2022
@mengzhuo
Copy link
Contributor

cc @golang/arm

@erifan
Copy link

erifan commented Jun 22, 2022

I can't reproduce the problem with the latest code, but with go1.18.3. Maybe this problem has been fixed after go1.18.3 ?

$ go version
go version devel go1.19-527ace0ffa Sat Jun 18 00:48:50 2022 +0000 darwin/arm64

@578559967
Copy link
Author

More environment info:

$ ld -v
@(#)PROGRAM:ld  PROJECT:ld64-764
BUILD 11:22:55 Apr 28 2022
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
LTO support using: LLVM version 13.1.6, (clang-1316.0.21.2.5) (static support for 28, runtime is 28)
TAPI support using: Apple TAPI version 13.1.6 (tapi-1316.0.7.3)

@578559967
Copy link
Author

I can't reproduce the problem with the latest code, but with go1.18.3. Maybe this problem has been fixed after go1.18.3 ?

$ go version go version devel go1.19-527ace0ffa Sat Jun 18 00:48:50 2022 +0000 darwin/arm64

For 1.19, use this attachment:
test_1.19.go.tar.gz
It will output:

Field name not right:  92184 rstuvwxyz91761a91762abcdefghijklmnopqrstuvwxyz91762a91763abcdefghijklmnopqrstuvwxyz91763a91764abcdefghij

@578559967
Copy link
Author

Why I think this is a link bug, my analysis is as follows:

  1. The direct reason is that the types info saved in the binary gets mistakes:
    The field 'name' in type structField of reflect/type.go points to wrong address.
        type structField struct {
            name        name    // This field got wrong
            typ         *rtype
            offsetEmbed uintptr 
        }
        type name struct {
            bytes *byte    // this field points to wrong address
        }
  1. Then I debug the program and get the address of name which store the wrong address.
    As the address is an virtual address, I did some calculation and converted the address to an address in the executable binary which is 0x1008ac200.

  2. Then I use objdump --full-contents --macho ./test_1.18 to view the binary. The value at 0x1008ac200 is 4ebf4200 00001000.

  3. Then I convert the value to an address 0x10042bf4e, and find values start at the address in the binary. I got the chars which is the same as the output of the program.
    截屏2022-06-19 22 18 34

  4. The test code uses cgo.

  5. The go linker links all go code to an object file named go.o

  6. Then the go linker calls the host linker to link go.o and other object files to the final binary.

  7. I check the go.o and use the value nearby that address to locate the address in go.o. I found that the value stored in that address is right.

  8. So I think it may be a bug of the host linker which is /usr/bin/ld provided by apple. The linker does the relocation job wrong at that address.

  9. I modify the go linker to use lld provided by llvm to do the host link job. And the program works well and print "ok".

  10. I objdump the new binary and found that the value at that address is right.

  11. The address which stores the wrong value has an offset of 0x800000 from the __rodata section. This may be a special address handled in the host linker.

@erifan
Copy link

erifan commented Jun 22, 2022

I can't reproduce the problem with the latest code, but with go1.18.3. Maybe this problem has been fixed after go1.18.3 ?
$ go version go version devel go1.19-527ace0ffa Sat Jun 18 00:48:50 2022 +0000 darwin/arm64

For 1.19, use this attachment: test_1.19.go.tar.gz It will output:

Field name not right:  92184 rstuvwxyz91761a91762abcdefghijklmnopqrstuvwxyz91762a91763abcdefghijklmnopqrstuvwxyz91763a91764abcdefghij

This cannot be reproduced either.

@578559967
Copy link
Author

I can't reproduce the problem with the latest code, but with go1.18.3. Maybe this problem has been fixed after go1.18.3 ?
$ go version go version devel go1.19-527ace0ffa Sat Jun 18 00:48:50 2022 +0000 darwin/arm64

For 1.19, use this attachment: test_1.19.go.tar.gz It will output:

Field name not right:  92184 rstuvwxyz91761a91762abcdefghijklmnopqrstuvwxyz91762a91763abcdefghijklmnopqrstuvwxyz91763a91764abcdefghij

This cannot be reproduced either.

Do you use mac with arm64?
What's your default ld version?

@erifan
Copy link

erifan commented Jun 22, 2022

Do you use mac with arm64?

Yes

What's your default ld version?

$ ld -v
@(#)PROGRAM:ld PROJECT:ld64-609.8
BUILD 15:07:50 Dec 18 2020
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
LTO support using: LLVM version 12.0.0, (clang-1200.0.32.29) (static support for 27, runtime is 27)
TAPI support using: Apple TAPI version 12.0.0 (tapi-1200.0.23.5)

@cherrymui
Copy link
Member

I cannot reproduce either with Go tip (be0b2a3) and test_1.19.go.tar.gz, with both ld64-816 and ld64-764.

@cherrymui cherrymui added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jun 22, 2022
@578559967
Copy link
Author

1.19beta1 can reproduce with test_1.19.go.tar.gz.

Maybe this commit has fixed the bug somehow: https://go.dev/cl/411912
I don't know the root cause and not sure whether this commit fixed it completely.
If it really fixed the bug, I think this commit should be picked back to 1.18 and 1.17.

@578559967
Copy link
Author

Any update on this?

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 13, 2022
@joedian
Copy link

joedian commented Nov 16, 2022

@578559967 does it reproduce with the lates 1.19 as well?

@578559967
Copy link
Author

No, the latest 1.19 works well. Maybe this commit has fixed the bug somehow: https://go.dev/cl/411912

@578559967 does it reproduce with the lates 1.19 as well?

@seankhliao seankhliao added WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. and removed WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. labels Dec 17, 2022
@cherrymui
Copy link
Member

This seems no longer reproduces. Closing. Feel free to reopen. Thanks.

@golang golang locked and limited conversation to collaborators Jan 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

8 participants