Skip to content

runtime: add crash stack support for 386 #65934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/runtime/asm.s
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ TEXT ·sigpanic0(SB),NOSPLIT,$0-0
TEXT ·mapinitnoop<ABIInternal>(SB),NOSPLIT,$0-0
RET

#ifndef GOARCH_386
#ifndef GOARCH_arm
#ifndef GOARCH_amd64
#ifndef GOARCH_arm64
Expand All @@ -38,3 +39,4 @@ TEXT ·switchToCrashStack0<ABIInternal>(SB),NOSPLIT,$0-0
#endif
#endif
#endif
#endif
50 changes: 40 additions & 10 deletions src/runtime/asm_386.s
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,35 @@ bad:
CALL AX
INT $3

// func switchToCrashStack0(fn func())
TEXT runtime·switchToCrashStack0(SB), NOSPLIT, $0-4
MOVL fn+0(FP), AX

get_tls(CX)
MOVL g(CX), BX // BX = g
MOVL g_m(BX), DX // DX = curm

// set g to gcrash
LEAL runtime·gcrash(SB), BX // g = &gcrash
MOVL DX, g_m(BX) // g.m = curm
MOVL BX, m_g0(DX) // curm.g0 = g
get_tls(CX)
MOVL BX, g(CX)

// switch to crashstack
MOVL (g_stack+stack_hi)(BX), DX
SUBL $(4*8), DX
MOVL DX, SP

// call target function
MOVL AX, DX
MOVL 0(AX), AX
CALL AX

// should never return
CALL runtime·abort(SB)
UNDEF

/*
* support for morestack
*/
Expand All @@ -408,11 +437,19 @@ bad:
// the top of a stack (for example, morestack calling newstack
// calling the scheduler calling newm calling gc), so we must
// record an argument size. For that purpose, it has no arguments.
TEXT runtime·morestack(SB),NOSPLIT,$0-0
TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
// Cannot grow scheduler stack (m->g0).
get_tls(CX)
MOVL g(CX), BX
MOVL g_m(BX), BX
MOVL g(CX), DI
MOVL g_m(DI), BX

// Set g->sched to context in f.
MOVL 0(SP), AX // f's PC
MOVL AX, (g_sched+gobuf_pc)(DI)
LEAL 4(SP), AX // f's SP
MOVL AX, (g_sched+gobuf_sp)(DI)
MOVL DX, (g_sched+gobuf_ctxt)(DI)

MOVL m_g0(BX), SI
CMPL g(CX), SI
JNE 3(PC)
Expand All @@ -437,13 +474,6 @@ TEXT runtime·morestack(SB),NOSPLIT,$0-0
MOVL g(CX), SI
MOVL SI, (m_morebuf+gobuf_g)(BX)

// Set g->sched to context in f.
MOVL 0(SP), AX // f's PC
MOVL AX, (g_sched+gobuf_pc)(SI)
LEAL 4(SP), AX // f's SP
MOVL AX, (g_sched+gobuf_sp)(SI)
MOVL DX, (g_sched+gobuf_ctxt)(SI)

// Call newstack on m->g0's stack.
MOVL m_g0(BX), BP
MOVL BP, g(CX)
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/proc.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ func switchToCrashStack(fn func()) {
// Disable crash stack on Windows for now. Apparently, throwing an exception
// on a non-system-allocated crash stack causes EXCEPTION_STACK_OVERFLOW and
// hangs the process (see issue 63938).
const crashStackImplemented = (GOARCH == "amd64" || GOARCH == "arm" || GOARCH == "arm64" || GOARCH == "loong64" || GOARCH == "mips64" || GOARCH == "mips64le" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64" || GOARCH == "s390x" || GOARCH == "wasm") && GOOS != "windows"
const crashStackImplemented = (GOARCH == "386" || GOARCH == "amd64" || GOARCH == "arm" || GOARCH == "arm64" || GOARCH == "loong64" || GOARCH == "mips64" || GOARCH == "mips64le" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64" || GOARCH == "s390x" || GOARCH == "wasm") && GOOS != "windows"

//go:noescape
func switchToCrashStack0(fn func()) // in assembly
Expand Down