diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2014-08-25 23:47:44 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2014-08-25 23:47:44 +0400 |
commit | 12b244394c45b1fdc1532e83972b3a579ff3bf8f (patch) | |
tree | 0f93870c29e631c8befe5bfc624d69ce0be43331 /winsup | |
parent | 5578cc4b73ddb1e99715643ec5768e4402da830f (diff) |
* 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.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 14 | ||||
-rw-r--r-- | winsup/cygwin/cygtls.cc | 8 | ||||
-rw-r--r-- | 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,5 +1,19 @@ 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> + * cygtls.cc (_cygtls::remove): Revert previous patch. * cygtls.h (struct _local_storage): Move pathbufs back here. (class san/x86_64): Revert class. Save and restore pathbufs counters 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; |