こんにちは駆け出しエンジニアです!!!Go初心者なんでここが気になり調べました!!!!!!!!!
$ go version
go version go1.14 linux/amd64
$ go build -buildmode=c-shared -ldflags=-w -o hello.so hello.go
$ LANG=C readelf -Wx .init_array hello.so
Hex dump of section '.init_array':
0x00317068 f0930600 00000000 80680c00 00000000 .........h......
$ nm hello.so| grep 000c6880
00000000000c6880 t _rt0_amd64_linux_lib
ソースもみる。手元のバージョンがちょっと古いけど全体的なロジックは変わらないだろう。たぶん。おそらく。
src/runtime/rt0_linux_amd64.s をみると
TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0
JMP _rt0_amd64_lib(SB)
で src/runtime/asm_amd64.s を読むとこのへんから初期化がはじまっていることがわかる。
// _rt0_amd64_lib is common startup code for most amd64 systems when
// using -buildmode=c-archive or -buildmode=c-shared. The linker will
// arrange to invoke this function as a global constructor (for
// c-archive) or when the shared library is loaded (for c-shared).
// We expect argc and argv to be passed in the usual C ABI registers
// DI and SI.
TEXT _rt0_amd64_lib(SB),NOSPLIT,$0
// Transition from C ABI to Go ABI.
PUSH_REGS_HOST_TO_ABI0()
MOVQ DI, _rt0_amd64_lib_argc<>(SB)
MOVQ SI, _rt0_amd64_lib_argv<>(SB)
// Synchronous initialization.
CALL runtime·libpreinit(SB)
// Create a new thread to finish Go runtime initialization.
MOVQ _cgo_sys_thread_create(SB), AX
TESTQ AX, AX
JZ nocgo
// We're calling back to C.
// Align stack per ELF ABI requirements.
MOVQ SP, BX // Callee-save in C ABI
ANDQ $~15, SP
MOVQ $_rt0_amd64_lib_go(SB), DI
MOVQ $0, SI
CALL AX
MOVQ BX, SP
JMP restore
いかがでしたか?