x86 特定平台的 Go 引导(amd64)
所有操作都是基于 go 1.13,CentOS 6.3。
1
2
# -gcflags "-N -l" 关闭编译器代码优化和函数内联
go build -gcflags "-N -l" -o hello hello.go
开始
1
2
3
4
5
6
7
8
gdb hello
(gdb) info files
Local exec file:
Entry point: 0x454d30
(gdb) b *0x454d30
Breakpoint 1 at 0x454d30: file /usr/lib/golang/src/runtime/rt0_linux_amd64.s, line 8.
查看 rt0_linux_amd64.s 代码
TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8
JMP _rt0_amd64(SB)
通过查找,发现在 asm_amd64.s 中有 _rt0_amd64
// _rt0_amd64 is common startup code for most amd64 systems when using
// internal linking. This is the entry point for the program from the
// kernel for an ordinary -buildmode=exe program. The stack holds the
// number of arguments and the C-style argv.
TEXT _rt0_amd64(SB),NOSPLIT,$-8
MOVQ 0(SP), DI // argc
LEAQ 8(SP), SI // argv
JMP runtime·rt0_go(SB)
1
2
(gdb) b runtime.rt0_go
Breakpoint 2 at 0x451370: file /usr/lib/golang/src/runtime/asm_amd64.s, line 89.
TEXT runtime·rt0_go(SB),NOSPLIT,$0
...
MOVL 16(SP), AX // copy argc
MOVL AX, 0(SP)
MOVQ 24(SP), AX // copy argv
MOVQ AX, 8(SP)
CALL runtime·args(SB)
CALL runtime·osinit(SB)
CALL runtime·schedinit(SB)
// create a new goroutine to start program
MOVQ $runtime·mainPC(SB), AX // entry
PUSHQ AX
PUSHQ $0 // arg size
CALL runtime·newproc(SB)
POPQ AX
POPQ AX
// start this M
CALL runtime·mstart(SB)
CALL runtime·abort(SB) // mstart should never return
RET
// Prevent dead-code elimination of debugCallV1, which is
// intended to be called by debuggers.
MOVQ $runtime·debugCallV1(SB), AX
RET
DATA runtime·mainPC+0(SB)/8,$runtime·main(SB)
GLOBL runtime·mainPC(SB),RODATA,$8
引导过程完成了,从此开始为 Golang 代码。
1
2
(gdb) b runtime.main
Breakpoint 3 at 0x42aea0: file /usr/lib/golang/src/runtime/proc.go, line 113