Link bug on darwin arm64(Mac M1 Max)

137 views
Skip to first unread message

任长风

unread,
Jun 19, 2022, 8:00:25 PM6/19/22
to golang-nuts
System: macOS Monterey 12.1
               darwin arm64
               Apple M1 Max
Go version: 1.18.3/1.18.2/1.18.1/1.17.10/1.17.6
ld version
@(#)PROGRAM:ld  PROJECT:ld64-764
BUILD 11:22:55 Apr 28 2022

Program: See the attachements test_1.18.go、test_1.17.6.go

For go 1.18.3/1.18.2/1.18.1:
  What you did:
    go run test_1.18.go
  What happened:
    Field name not right:  92292 rstuvwxyz91869a91870abcdefghijklmnopqrstuvwxyz91870a91871abcdefghijklmnopqrstuvwxyz91871a91872abcdefghij
  What you expected to happend instead:
     ok

Use other attachements for go1.17.6 to reproduce the same bug.

These programs works as expect on other platforms. I have tested on linux and mac with intel chip.

test_1.18.go

任长风

unread,
Jun 19, 2022, 9:04:54 PM6/19/22
to golang-nuts
Add attachements for go1.17.6.

test_1.17.6.go

任长风

unread,
Jun 19, 2022, 9:11:43 PM6/19/22
to golang-nuts

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
        }
2. 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.
3. Then I use objdump --full-contents --macho ./test_1.18 to view the binary. The value at 0x1008ac200 is 4ebf4200 00001000.
4. 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.png
5. The test code uses cgo.
6. The go linker links all go code to an object file named go.o
7. Then the go linker calls the host linker to link go.o and other object files to the final binary.
8. 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.
9. 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.
10. 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".
11. I objdump the new binary and found that the value at that address is right.
12. 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.
 

在2022年6月20日星期一 UTC+8 09:04:54<任长风> 写道:
Add attachements for go1.17.6.

Ian Lance Taylor

unread,
Jun 20, 2022, 2:02:39 AM6/20/22
to 任长风, golang-nuts
On Sun, Jun 19, 2022 at 6:04 PM 任长风 <rencha...@gmail.com> wrote:
>
> Add attachements for go1.17.6.

Are you trying to report a bug? If so, please file it as
https://go.dev/issue and follow the instructions there. Thanks.

(I tried running your file with tip on linux/amd64 and it seemed to work fine.)

Ian
Reply all
Reply to author
Forward
0 new messages