From 12b244394c45b1fdc1532e83972b3a579ff3bf8f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 25 Aug 2014 19:47:44 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 14 ++++++++++++++ winsup/cygwin/cygtls.cc | 8 ++++++++ winsup/cygwin/cygtls.h | 36 +++++++++++++++++++----------------- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a7cba5538..a6ee9dd4e 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,17 @@ +2014-08-25 Corinna Vinschen + + * 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 * cygtls.cc (_cygtls::remove): Revert previous patch. diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index 5cc9405eb..2eaae9437 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -200,3 +200,11 @@ _cygtls::remove (DWORD wait) cygheap->remove_tls (this, 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 diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 3c19ab369..f09444e07 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -51,8 +51,15 @@ class tls_pathbuf /* 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 mov statements in sigbe! */ - uint32_t c_cnt; - uint32_t w_cnt; + union + { + struct + { + uint32_t c_cnt; + uint32_t w_cnt; + }; + uint64_t _counters; + }; char *c_buf[TP_NUM_C_BUFS]; WCHAR *w_buf[TP_NUM_W_BUFS]; @@ -291,28 +298,24 @@ extern _cygtls *_sig_tls; #ifdef __x86_64__ class san { - unsigned _c_cnt; - unsigned _w_cnt; + uint64_t _cnt; public: - void setup () __attribute__ ((always_inline)) + san () __attribute__ ((always_inline)) { - _c_cnt = _my_tls.locals.pathbufs.c_cnt; - _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; + _cnt = _my_tls.locals.pathbufs._counters; } + /* 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 class san { san *_clemente; jmp_buf _context; - unsigned _c_cnt; - unsigned _w_cnt; + uint32_t _c_cnt; + uint32_t _w_cnt; public: int setup () __attribute__ ((always_inline)) { @@ -356,8 +359,8 @@ public: #define __try \ { \ __label__ __l_try, __l_except, __l_endtry; \ - san __sebastian; \ __mem_barrier; \ + san __sebastian; \ __asm__ goto ("\n" \ " .seh_handler _ZN9exception7myfaultEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, @except \n" \ " .seh_handlerdata \n" \ @@ -365,7 +368,6 @@ public: " .rva %l[__l_try],%l[__l_endtry],%l[__l_except],%l[__l_except] \n" \ " .seh_code \n" \ : : : : __l_try, __l_endtry, __l_except); \ - __sebastian.setup (); \ { \ __l_try: \ __mem_barrier; -- 2.43.5