Skip to content
Snippets Groups Projects
Commit 43f911b0 authored by qmuntal's avatar qmuntal Committed by Gopher Robot
Browse files

runtime: remove NOFRAME from asmcgocall, systemstack and mcall

This CL removes the NOFRAME flag from runtime.asmcgocall,
runtime.systemstack and runtime.mcall so the compiler can place
the frame pointer on the stack.

This will help unwinding cgo stack frames, and might be all what's
needed for tools that only use the frame pointer to unwind the stack.
That's not the case for gdb, which uses DWARF CFI, and windbg,
which uses SEH. Yet, having the frame pointer correctly set lays
the foundation for supporting cgo unwinding with DWARF CFI and SEH.

Updates #58378

Change-Id: I7655363b3fb619acccd9d5a7f0e3d3dec953cd52
Reviewed-on: https://go-review.googlesource.com/c/go/+/472195


Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Reviewed-by: default avatarCherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: default avatarMichael Pratt <mpratt@google.com>
parent b6f29d23
No related branches found
No related tags found
No related merge requests found
...@@ -425,11 +425,14 @@ TEXT gogo<>(SB), NOSPLIT, $0 ...@@ -425,11 +425,14 @@ TEXT gogo<>(SB), NOSPLIT, $0
// Switch to m->g0's stack, call fn(g). // Switch to m->g0's stack, call fn(g).
// Fn must never return. It should gogo(&g->sched) // Fn must never return. It should gogo(&g->sched)
// to keep running g. // to keep running g.
TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8 TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT, $0-8
MOVQ AX, DX // DX = fn MOVQ AX, DX // DX = fn
// save state in g->sched // Save state in g->sched.
MOVQ 0(SP), BX // caller's PC // The original frame pointer is stored in BP,
// which is useful for stack unwinding.
MOVQ SP, BX // hide (SP) reads from vet
MOVQ 8(BX), BX // caller's PC
MOVQ BX, (g_sched+gobuf_pc)(R14) MOVQ BX, (g_sched+gobuf_pc)(R14)
LEAQ fn+0(FP), BX // caller's SP LEAQ fn+0(FP), BX // caller's SP
MOVQ BX, (g_sched+gobuf_sp)(R14) MOVQ BX, (g_sched+gobuf_sp)(R14)
...@@ -459,11 +462,17 @@ goodm: ...@@ -459,11 +462,17 @@ goodm:
// lives at the bottom of the G stack from the one that lives // lives at the bottom of the G stack from the one that lives
// at the top of the system stack because the one at the top of // at the top of the system stack because the one at the top of
// the system stack terminates the stack walk (see topofstack()). // the system stack terminates the stack walk (see topofstack()).
// The frame layout needs to match systemstack
// so that it can pretend to be systemstack_switch.
TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0 TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
UNDEF
// Make sure this function is not leaf,
// so the frame is saved.
CALL runtime·abort(SB)
RET RET
// func systemstack(fn func()) // func systemstack(fn func())
TEXT runtime·systemstack(SB), NOSPLIT|NOFRAME, $0-8 TEXT runtime·systemstack(SB), NOSPLIT, $0-8
MOVQ fn+0(FP), DI // DI = fn MOVQ fn+0(FP), DI // DI = fn
get_tls(CX) get_tls(CX)
MOVQ g(CX), AX // AX = g MOVQ g(CX), AX // AX = g
...@@ -479,16 +488,17 @@ TEXT runtime·systemstack(SB), NOSPLIT|NOFRAME, $0-8 ...@@ -479,16 +488,17 @@ TEXT runtime·systemstack(SB), NOSPLIT|NOFRAME, $0-8
CMPQ AX, m_curg(BX) CMPQ AX, m_curg(BX)
JNE bad JNE bad
// switch stacks // Switch stacks.
// save our state in g->sched. Pretend to // The original frame pointer is stored in BP,
// which is useful for stack unwinding.
// Save our state in g->sched. Pretend to
// be systemstack_switch if the G stack is scanned. // be systemstack_switch if the G stack is scanned.
CALL gosave_systemstack_switch<>(SB) CALL gosave_systemstack_switch<>(SB)
// switch to g0 // switch to g0
MOVQ DX, g(CX) MOVQ DX, g(CX)
MOVQ DX, R14 // set the g register MOVQ DX, R14 // set the g register
MOVQ (g_sched+gobuf_sp)(DX), BX MOVQ (g_sched+gobuf_sp)(DX), SP
MOVQ BX, SP
// call target function // call target function
MOVQ DI, DX MOVQ DI, DX
...@@ -502,7 +512,9 @@ TEXT runtime·systemstack(SB), NOSPLIT|NOFRAME, $0-8 ...@@ -502,7 +512,9 @@ TEXT runtime·systemstack(SB), NOSPLIT|NOFRAME, $0-8
MOVQ m_curg(BX), AX MOVQ m_curg(BX), AX
MOVQ AX, g(CX) MOVQ AX, g(CX)
MOVQ (g_sched+gobuf_sp)(AX), SP MOVQ (g_sched+gobuf_sp)(AX), SP
MOVQ (g_sched+gobuf_bp)(AX), BP
MOVQ $0, (g_sched+gobuf_sp)(AX) MOVQ $0, (g_sched+gobuf_sp)(AX)
MOVQ $0, (g_sched+gobuf_bp)(AX)
RET RET
noswitch: noswitch:
...@@ -511,6 +523,9 @@ noswitch: ...@@ -511,6 +523,9 @@ noswitch:
// at an intermediate systemstack. // at an intermediate systemstack.
MOVQ DI, DX MOVQ DI, DX
MOVQ 0(DI), DI MOVQ 0(DI), DI
// The function epilogue is not called on a tail call.
// Pop BP from the stack to simulate it.
POPQ BP
JMP DI JMP DI
bad: bad:
...@@ -571,6 +586,7 @@ TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0 ...@@ -571,6 +586,7 @@ TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
MOVQ m_g0(BX), BX MOVQ m_g0(BX), BX
MOVQ BX, g(CX) MOVQ BX, g(CX)
MOVQ (g_sched+gobuf_sp)(BX), SP MOVQ (g_sched+gobuf_sp)(BX), SP
MOVQ (g_sched+gobuf_bp)(BX), BP
CALL runtime·newstack(SB) CALL runtime·newstack(SB)
CALL runtime·abort(SB) // crash if newstack returns CALL runtime·abort(SB) // crash if newstack returns
RET RET
...@@ -769,11 +785,15 @@ TEXT ·publicationBarrier<ABIInternal>(SB),NOSPLIT,$0-0 ...@@ -769,11 +785,15 @@ TEXT ·publicationBarrier<ABIInternal>(SB),NOSPLIT,$0-0
// Save state of caller into g->sched, // Save state of caller into g->sched,
// but using fake PC from systemstack_switch. // but using fake PC from systemstack_switch.
// Must only be called from functions with no locals ($0) // Must only be called from functions with frame pointer
// or else unwinding from systemstack_switch is incorrect. // and without locals ($0) or else unwinding from
// systemstack_switch is incorrect.
// Smashes R9. // Smashes R9.
TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0 TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
MOVQ $runtime·systemstack_switch(SB), R9 // Take systemstack_switch PC and add 8 bytes to skip
// the prologue. The final location does not matter
// as long as we are between the prologue and the epilogue.
MOVQ $runtime·systemstack_switch+8(SB), R9
MOVQ R9, (g_sched+gobuf_pc)(R14) MOVQ R9, (g_sched+gobuf_pc)(R14)
LEAQ 8(SP), R9 LEAQ 8(SP), R9
MOVQ R9, (g_sched+gobuf_sp)(R14) MOVQ R9, (g_sched+gobuf_sp)(R14)
...@@ -789,11 +809,10 @@ TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0 ...@@ -789,11 +809,10 @@ TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
// func asmcgocall_no_g(fn, arg unsafe.Pointer) // func asmcgocall_no_g(fn, arg unsafe.Pointer)
// Call fn(arg) aligned appropriately for the gcc ABI. // Call fn(arg) aligned appropriately for the gcc ABI.
// Called on a system stack, and there may be no g yet (during needm). // Called on a system stack, and there may be no g yet (during needm).
TEXT ·asmcgocall_no_g(SB),NOSPLIT|NOFRAME,$0-16 TEXT ·asmcgocall_no_g(SB),NOSPLIT,$32-16
MOVQ fn+0(FP), AX MOVQ fn+0(FP), AX
MOVQ arg+8(FP), BX MOVQ arg+8(FP), BX
MOVQ SP, DX MOVQ SP, DX
SUBQ $32, SP
ANDQ $~15, SP // alignment ANDQ $~15, SP // alignment
MOVQ DX, 8(SP) MOVQ DX, 8(SP)
MOVQ BX, DI // DI = first argument in AMD64 ABI MOVQ BX, DI // DI = first argument in AMD64 ABI
...@@ -807,7 +826,7 @@ TEXT ·asmcgocall_no_g(SB),NOSPLIT|NOFRAME,$0-16 ...@@ -807,7 +826,7 @@ TEXT ·asmcgocall_no_g(SB),NOSPLIT|NOFRAME,$0-16
// Call fn(arg) on the scheduler stack, // Call fn(arg) on the scheduler stack,
// aligned appropriately for the gcc ABI. // aligned appropriately for the gcc ABI.
// See cgocall.go for more details. // See cgocall.go for more details.
TEXT ·asmcgocall(SB),NOSPLIT|NOFRAME,$0-20 TEXT ·asmcgocall(SB),NOSPLIT,$0-20
MOVQ fn+0(FP), AX MOVQ fn+0(FP), AX
MOVQ arg+8(FP), BX MOVQ arg+8(FP), BX
...@@ -830,6 +849,8 @@ TEXT ·asmcgocall(SB),NOSPLIT|NOFRAME,$0-20 ...@@ -830,6 +849,8 @@ TEXT ·asmcgocall(SB),NOSPLIT|NOFRAME,$0-20
JEQ nosave JEQ nosave
// Switch to system stack. // Switch to system stack.
// The original frame pointer is stored in BP,
// which is useful for stack unwinding.
CALL gosave_systemstack_switch<>(SB) CALL gosave_systemstack_switch<>(SB)
MOVQ SI, g(CX) MOVQ SI, g(CX)
MOVQ (g_sched+gobuf_sp)(SI), SP MOVQ (g_sched+gobuf_sp)(SI), SP
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment