Go 代码引导过程

Go boot

Posted by cslqm on December 14, 2020

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