Skip to content

Commit 43f911b

Browse files
qmuntalgopherbot
authored andcommitted
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 <[email protected]> Auto-Submit: Michael Pratt <[email protected]> Reviewed-by: Cherry Mui <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Michael Pratt <[email protected]>
1 parent b6f29d2 commit 43f911b

File tree

1 file changed

+35
-14
lines changed

1 file changed

+35
-14
lines changed

src/runtime/asm_amd64.s

+35-14
Original file line numberDiff line numberDiff line change
@@ -425,11 +425,14 @@ TEXT gogo<>(SB), NOSPLIT, $0
425425
// Switch to m->g0's stack, call fn(g).
426426
// Fn must never return. It should gogo(&g->sched)
427427
// to keep running g.
428-
TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
428+
TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT, $0-8
429429
MOVQ AX, DX // DX = fn
430430

431-
// save state in g->sched
432-
MOVQ 0(SP), BX // caller's PC
431+
// Save state in g->sched.
432+
// The original frame pointer is stored in BP,
433+
// which is useful for stack unwinding.
434+
MOVQ SP, BX // hide (SP) reads from vet
435+
MOVQ 8(BX), BX // caller's PC
433436
MOVQ BX, (g_sched+gobuf_pc)(R14)
434437
LEAQ fn+0(FP), BX // caller's SP
435438
MOVQ BX, (g_sched+gobuf_sp)(R14)
@@ -459,11 +462,17 @@ goodm:
459462
// lives at the bottom of the G stack from the one that lives
460463
// at the top of the system stack because the one at the top of
461464
// the system stack terminates the stack walk (see topofstack()).
465+
// The frame layout needs to match systemstack
466+
// so that it can pretend to be systemstack_switch.
462467
TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
468+
UNDEF
469+
// Make sure this function is not leaf,
470+
// so the frame is saved.
471+
CALL runtime·abort(SB)
463472
RET
464473

465474
// func systemstack(fn func())
466-
TEXT runtime·systemstack(SB), NOSPLIT|NOFRAME, $0-8
475+
TEXT runtime·systemstack(SB), NOSPLIT, $0-8
467476
MOVQ fn+0(FP), DI // DI = fn
468477
get_tls(CX)
469478
MOVQ g(CX), AX // AX = g
@@ -479,16 +488,17 @@ TEXT runtime·systemstack(SB), NOSPLIT|NOFRAME, $0-8
479488
CMPQ AX, m_curg(BX)
480489
JNE bad
481490

482-
// switch stacks
483-
// save our state in g->sched. Pretend to
491+
// Switch stacks.
492+
// The original frame pointer is stored in BP,
493+
// which is useful for stack unwinding.
494+
// Save our state in g->sched. Pretend to
484495
// be systemstack_switch if the G stack is scanned.
485496
CALL gosave_systemstack_switch<>(SB)
486497

487498
// switch to g0
488499
MOVQ DX, g(CX)
489500
MOVQ DX, R14 // set the g register
490-
MOVQ (g_sched+gobuf_sp)(DX), BX
491-
MOVQ BX, SP
501+
MOVQ (g_sched+gobuf_sp)(DX), SP
492502

493503
// call target function
494504
MOVQ DI, DX
@@ -502,7 +512,9 @@ TEXT runtime·systemstack(SB), NOSPLIT|NOFRAME, $0-8
502512
MOVQ m_curg(BX), AX
503513
MOVQ AX, g(CX)
504514
MOVQ (g_sched+gobuf_sp)(AX), SP
515+
MOVQ (g_sched+gobuf_bp)(AX), BP
505516
MOVQ $0, (g_sched+gobuf_sp)(AX)
517+
MOVQ $0, (g_sched+gobuf_bp)(AX)
506518
RET
507519

508520
noswitch:
@@ -511,6 +523,9 @@ noswitch:
511523
// at an intermediate systemstack.
512524
MOVQ DI, DX
513525
MOVQ 0(DI), DI
526+
// The function epilogue is not called on a tail call.
527+
// Pop BP from the stack to simulate it.
528+
POPQ BP
514529
JMP DI
515530

516531
bad:
@@ -571,6 +586,7 @@ TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
571586
MOVQ m_g0(BX), BX
572587
MOVQ BX, g(CX)
573588
MOVQ (g_sched+gobuf_sp)(BX), SP
589+
MOVQ (g_sched+gobuf_bp)(BX), BP
574590
CALL runtime·newstack(SB)
575591
CALL runtime·abort(SB) // crash if newstack returns
576592
RET
@@ -769,11 +785,15 @@ TEXT ·publicationBarrier<ABIInternal>(SB),NOSPLIT,$0-0
769785

770786
// Save state of caller into g->sched,
771787
// but using fake PC from systemstack_switch.
772-
// Must only be called from functions with no locals ($0)
773-
// or else unwinding from systemstack_switch is incorrect.
788+
// Must only be called from functions with frame pointer
789+
// and without locals ($0) or else unwinding from
790+
// systemstack_switch is incorrect.
774791
// Smashes R9.
775792
TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
776-
MOVQ $runtime·systemstack_switch(SB), R9
793+
// Take systemstack_switch PC and add 8 bytes to skip
794+
// the prologue. The final location does not matter
795+
// as long as we are between the prologue and the epilogue.
796+
MOVQ $runtime·systemstack_switch+8(SB), R9
777797
MOVQ R9, (g_sched+gobuf_pc)(R14)
778798
LEAQ 8(SP), R9
779799
MOVQ R9, (g_sched+gobuf_sp)(R14)
@@ -789,11 +809,10 @@ TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
789809
// func asmcgocall_no_g(fn, arg unsafe.Pointer)
790810
// Call fn(arg) aligned appropriately for the gcc ABI.
791811
// Called on a system stack, and there may be no g yet (during needm).
792-
TEXT ·asmcgocall_no_g(SB),NOSPLIT|NOFRAME,$0-16
812+
TEXT ·asmcgocall_no_g(SB),NOSPLIT,$32-16
793813
MOVQ fn+0(FP), AX
794814
MOVQ arg+8(FP), BX
795815
MOVQ SP, DX
796-
SUBQ $32, SP
797816
ANDQ $~15, SP // alignment
798817
MOVQ DX, 8(SP)
799818
MOVQ BX, DI // DI = first argument in AMD64 ABI
@@ -807,7 +826,7 @@ TEXT ·asmcgocall_no_g(SB),NOSPLIT|NOFRAME,$0-16
807826
// Call fn(arg) on the scheduler stack,
808827
// aligned appropriately for the gcc ABI.
809828
// See cgocall.go for more details.
810-
TEXT ·asmcgocall(SB),NOSPLIT|NOFRAME,$0-20
829+
TEXT ·asmcgocall(SB),NOSPLIT,$0-20
811830
MOVQ fn+0(FP), AX
812831
MOVQ arg+8(FP), BX
813832

@@ -830,6 +849,8 @@ TEXT ·asmcgocall(SB),NOSPLIT|NOFRAME,$0-20
830849
JEQ nosave
831850

832851
// Switch to system stack.
852+
// The original frame pointer is stored in BP,
853+
// which is useful for stack unwinding.
833854
CALL gosave_systemstack_switch<>(SB)
834855
MOVQ SI, g(CX)
835856
MOVQ (g_sched+gobuf_sp)(SI), SP

0 commit comments

Comments
 (0)