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.
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.