1
0
mirror of https://github.com/golang/go synced 2024-11-24 23:17:57 -07:00

runtime: correct seh installation during callbacks

Every time we enter callback from Windows, it is
possible that go exception handler is not at the top
of per-thread exception handlers chain. So it needs
to be installed again. At this moment this is done
by replacing top SEH frame with SEH frame as at time
of syscall for the time of callback. This is incorrect,
because, if exception strike, we won't be able to call
any exception handlers installed inside syscall,
because they are not in the chain. This changes
procedure to add new SEH frame on top of existing
chain instead.

I also removed m sehframe field, because I don't
think it is needed. We use single global exception
handler everywhere.

R=golang-dev, r
CC=golang-dev, hectorchu
https://golang.org/cl/4832060
This commit is contained in:
Alex Brainman 2011-08-10 17:17:28 +10:00
parent 8fced60a72
commit 9c774c3f26
2 changed files with 15 additions and 14 deletions

View File

@ -248,12 +248,9 @@ struct M
uint32 freghi[16]; // D[i] msb and F[i+16] uint32 freghi[16]; // D[i] msb and F[i+16]
uint32 fflag; // floating point compare flags uint32 fflag; // floating point compare flags
#ifdef __WINDOWS__ #ifdef __WINDOWS__
void* sehframe;
#ifdef _64BIT #ifdef _64BIT
void* gostack; void* gostack;
#endif #endif
#endif #endif
}; };

View File

@ -14,8 +14,6 @@ TEXT runtime·stdcall_raw(SB),7,$0
// Switch to m->g0 if needed. // Switch to m->g0 if needed.
get_tls(DI) get_tls(DI)
MOVL m(DI), DX MOVL m(DI), DX
MOVL 0(FS), SI
MOVL SI, m_sehframe(DX)
MOVL m_g0(DX), SI MOVL m_g0(DX), SI
CMPL g(DI), SI CMPL g(DI), SI
MOVL SP, BX MOVL SP, BX
@ -116,7 +114,7 @@ TEXT runtime·ctrlhandler(SB),7,$0
MOVL SP, BX MOVL SP, BX
// setup dummy m, g // setup dummy m, g
SUBL $(m_sehframe+4), SP // at least space for m_sehframe SUBL $(m_fflag+4), SP // at least space for m_fflag
LEAL m_tls(SP), CX LEAL m_tls(SP), CX
MOVL CX, 0x2c(FS) MOVL CX, 0x2c(FS)
MOVL SP, m(CX) MOVL SP, m(CX)
@ -159,33 +157,39 @@ TEXT runtime·callbackasm+0(SB),7,$0
ADDL $4, DX // extend argsize by size of return value ADDL $4, DX // extend argsize by size of return value
// save registers as required for windows callback // save registers as required for windows callback
PUSHL 0(FS)
PUSHL DI PUSHL DI
PUSHL SI PUSHL SI
PUSHL BP PUSHL BP
PUSHL BX PUSHL BX
// set up SEH frame again
PUSHL $runtime·sigtramp(SB)
PUSHL 0(FS)
MOVL SP, 0(FS)
// callback parameters
PUSHL DX PUSHL DX
PUSHL CX PUSHL CX
PUSHL AX PUSHL AX
// reinstall our SEH handler
get_tls(CX)
MOVL m(CX), CX
MOVL m_sehframe(CX), CX
MOVL CX, 0(FS)
CLD CLD
CALL runtime·cgocallback(SB) CALL runtime·cgocallback(SB)
// restore registers as required for windows callback
POPL AX POPL AX
POPL CX POPL CX
POPL DX POPL DX
// pop SEH frame
POPL 0(FS)
POPL BX
// restore registers as required for windows callback
POPL BX POPL BX
POPL BP POPL BP
POPL SI POPL SI
POPL DI POPL DI
POPL 0(FS)
CLD CLD
MOVL -4(CX)(DX*1), AX MOVL -4(CX)(DX*1), AX