* cygtls.cc (san::leave/x86_64): Implement.

* cygtls.h (class tls_pathbuf): Move counter variables into a union.
	Add 64 bit element _counters covering both counter variables to
	optimize save and restore operations.
	(class san/x86_64): Only store single 64 bit value.
	(san::san/x86_64): Implement.
	(san::leave/x86_64): Only declare here, as returns_twice function.
	Explain why.
	(class san/i686): Change type of _c_cnt and _w_cnt to uint32_t.
	(__try/x86_64): Move definition of __sebastian after the first memory
	barrier.  Drop __sebastian.setup call.
This commit is contained in:
Corinna Vinschen 2014-08-25 19:47:44 +00:00
parent 5578cc4b73
commit 12b244394c
3 changed files with 41 additions and 17 deletions

View File

@ -1,3 +1,17 @@
2014-08-25 Corinna Vinschen <corinna@vinschen.de>
* cygtls.cc (san::leave/x86_64): Implement.
* cygtls.h (class tls_pathbuf): Move counter variables into a union.
Add 64 bit element _counters covering both counter variables to
optimize save and restore operations.
(class san/x86_64): Only store single 64 bit value.
(san::san/x86_64): Implement.
(san::leave/x86_64): Only declare here, as returns_twice function.
Explain why.
(class san/i686): Change type of _c_cnt and _w_cnt to uint32_t.
(__try/x86_64): Move definition of __sebastian after the first memory
barrier. Drop __sebastian.setup call.
2014-08-25 Corinna Vinschen <corinna@vinschen.de> 2014-08-25 Corinna Vinschen <corinna@vinschen.de>
* cygtls.cc (_cygtls::remove): Revert previous patch. * cygtls.cc (_cygtls::remove): Revert previous patch.

View File

@ -200,3 +200,11 @@ _cygtls::remove (DWORD wait)
cygheap->remove_tls (this, wait); cygheap->remove_tls (this, wait);
remove_wq (wait); remove_wq (wait);
} }
#ifdef __x86_64__
void san::leave ()
{
/* Restore tls_pathbuf counters in case of error. */
_my_tls.locals.pathbufs._counters = _cnt;
}
#endif

View File

@ -51,8 +51,15 @@ class tls_pathbuf
/* Make sure that c_cnt and w_cnt are always the first two members of this /* Make sure that c_cnt and w_cnt are always the first two members of this
class, and never change the size (32 bit), unless you also change the class, and never change the size (32 bit), unless you also change the
mov statements in sigbe! */ mov statements in sigbe! */
union
{
struct
{
uint32_t c_cnt; uint32_t c_cnt;
uint32_t w_cnt; uint32_t w_cnt;
};
uint64_t _counters;
};
char *c_buf[TP_NUM_C_BUFS]; char *c_buf[TP_NUM_C_BUFS];
WCHAR *w_buf[TP_NUM_W_BUFS]; WCHAR *w_buf[TP_NUM_W_BUFS];
@ -291,28 +298,24 @@ extern _cygtls *_sig_tls;
#ifdef __x86_64__ #ifdef __x86_64__
class san class san
{ {
unsigned _c_cnt; uint64_t _cnt;
unsigned _w_cnt;
public: public:
void setup () __attribute__ ((always_inline)) san () __attribute__ ((always_inline))
{ {
_c_cnt = _my_tls.locals.pathbufs.c_cnt; _cnt = _my_tls.locals.pathbufs._counters;
_w_cnt = _my_tls.locals.pathbufs.w_cnt;
}
void leave () __attribute__ ((always_inline))
{
/* Restore tls_pathbuf counters in case of error. */
_my_tls.locals.pathbufs.c_cnt = _c_cnt;
_my_tls.locals.pathbufs.w_cnt = _w_cnt;
} }
/* This is the first thing called in the __except handler. The attribute
"returns_twice" makes sure that GCC disregards any register value set
earlier in the function, so this call serves as a register barrier. */
void leave () __attribute__ ((returns_twice));
}; };
#else #else
class san class san
{ {
san *_clemente; san *_clemente;
jmp_buf _context; jmp_buf _context;
unsigned _c_cnt; uint32_t _c_cnt;
unsigned _w_cnt; uint32_t _w_cnt;
public: public:
int setup () __attribute__ ((always_inline)) int setup () __attribute__ ((always_inline))
{ {
@ -356,8 +359,8 @@ public:
#define __try \ #define __try \
{ \ { \
__label__ __l_try, __l_except, __l_endtry; \ __label__ __l_try, __l_except, __l_endtry; \
san __sebastian; \
__mem_barrier; \ __mem_barrier; \
san __sebastian; \
__asm__ goto ("\n" \ __asm__ goto ("\n" \
" .seh_handler _ZN9exception7myfaultEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, @except \n" \ " .seh_handler _ZN9exception7myfaultEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, @except \n" \
" .seh_handlerdata \n" \ " .seh_handlerdata \n" \
@ -365,7 +368,6 @@ public:
" .rva %l[__l_try],%l[__l_endtry],%l[__l_except],%l[__l_except] \n" \ " .rva %l[__l_try],%l[__l_endtry],%l[__l_except],%l[__l_except] \n" \
" .seh_code \n" \ " .seh_code \n" \
: : : : __l_try, __l_endtry, __l_except); \ : : : : __l_try, __l_endtry, __l_except); \
__sebastian.setup (); \
{ \ { \
__l_try: \ __l_try: \
__mem_barrier; __mem_barrier;