1 // Methods for Exception Support for -*- C++ -*-
2 
3 // Copyright (C) 2014-2019 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 //
26 // ISO C++ 14882: 19.1  Exception classes
27 //
28 
29 // Enable hooks for support for the Transactional Memory TS (N4514).
30 #define _GLIBCXX_TM_TS_INTERNAL
31 void
32 _txnal_cow_string_C1_for_exceptions(void* that, const char* s, void* exc);
33 const char*
34 _txnal_cow_string_c_str(const void* that);
35 void
36 _txnal_cow_string_D1(void* that);
37 void
38 _txnal_cow_string_D1_commit(void* that);
39 void*
40 _txnal_logic_error_get_msg(void* e);
41 void*
42 _txnal_runtime_error_get_msg(void* e);
43 
44 // All exception classes still use the classic COW std::string.
45 #define _GLIBCXX_USE_CXX11_ABI 0
46 #define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1
47 #define __cow_string __cow_stringxxx
48 #include <stdexcept>
49 #include <system_error>
50 #undef __cow_string
51 
52 namespace std _GLIBCXX_VISIBILITY(default)
53 {
54 _GLIBCXX_BEGIN_NAMESPACE_VERSION
55 
56   // Copy/move constructors and assignment operators defined using COW string.
57   // These operations are noexcept even though copying a COW string is not,
58   // but we know that the string member in an exception has not been "leaked"
59   // so copying is a simple reference count increment.
60   // For the fully dynamic string moves are not noexcept (due to needing to
61   // allocate an empty string) so we just define the moves as copies here.
62 
logic_error(const logic_error & e)63   logic_error::logic_error(const logic_error& e) noexcept
64   : exception(e), _M_msg(e._M_msg) { }
65 
operator =(const logic_error & e)66   logic_error& logic_error::operator=(const logic_error& e) noexcept
67   { _M_msg = e._M_msg; return *this; }
68 
69 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
70   logic_error::logic_error(logic_error&& e) noexcept = default;
71 
72   logic_error&
73   logic_error::operator=(logic_error&& e) noexcept = default;
74 #else
logic_error(logic_error && e)75   logic_error::logic_error(logic_error&& e) noexcept
76   : exception(e), _M_msg(e._M_msg) { }
77 
78   logic_error&
operator =(logic_error && e)79   logic_error::operator=(logic_error&& e) noexcept
80   { _M_msg = e._M_msg; return *this; }
81 #endif
82 
runtime_error(const runtime_error & e)83   runtime_error::runtime_error(const runtime_error& e) noexcept
84   : exception(e), _M_msg(e._M_msg) { }
85 
86   runtime_error&
operator =(const runtime_error & e)87   runtime_error::operator=(const runtime_error& e) noexcept
88   { _M_msg = e._M_msg; return *this; }
89 
90 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
91   runtime_error::runtime_error(runtime_error&& e) noexcept = default;
92 
93   runtime_error&
94   runtime_error::operator=(runtime_error&& e) noexcept = default;
95 #else
runtime_error(runtime_error && e)96   runtime_error::runtime_error(runtime_error&& e) noexcept
97   : exception(e), _M_msg(e._M_msg) { }
98 
99   runtime_error&
operator =(runtime_error && e)100   runtime_error::operator=(runtime_error&& e) noexcept
101   { _M_msg = e._M_msg; return *this; }
102 #endif
103 
104   // New C++11 constructors:
105 
logic_error(const char * __arg)106   logic_error::logic_error(const char* __arg)
107   : exception(), _M_msg(__arg) { }
108 
domain_error(const char * __arg)109   domain_error::domain_error(const char* __arg)
110   : logic_error(__arg) { }
111 
invalid_argument(const char * __arg)112   invalid_argument::invalid_argument(const char* __arg)
113   : logic_error(__arg) { }
114 
length_error(const char * __arg)115   length_error::length_error(const char* __arg)
116   : logic_error(__arg) { }
117 
out_of_range(const char * __arg)118   out_of_range::out_of_range(const char* __arg)
119   : logic_error(__arg) { }
120 
runtime_error(const char * __arg)121   runtime_error::runtime_error(const char* __arg)
122   : exception(), _M_msg(__arg) { }
123 
range_error(const char * __arg)124   range_error::range_error(const char* __arg)
125   : runtime_error(__arg) { }
126 
overflow_error(const char * __arg)127   overflow_error::overflow_error(const char* __arg)
128   : runtime_error(__arg) { }
129 
underflow_error(const char * __arg)130   underflow_error::underflow_error(const char* __arg)
131   : runtime_error(__arg) { }
132 
133 #if _GLIBCXX_USE_DUAL_ABI
134   // Converting constructor from COW std::string to SSO string.
__sso_string(const string & s)135   __sso_string::__sso_string(const string& s)
136   : __sso_string(s.c_str(), s.length()) { }
137 
138   // Redefine __cow_string so that we can define and export its members
139   // in terms of the COW std::string.
140   struct __cow_string
141   {
142     union {
143       const char* _M_p;
144       char _M_bytes[sizeof(_M_p)];
145       std::string _M_str;
146     };
147 
148     __cow_string();
149     __cow_string(const std::string& s);
150     __cow_string(const char*, size_t n);
151     __cow_string(const __cow_string&) noexcept;
152     __cow_string& operator=(const __cow_string&) noexcept;
153     ~__cow_string();
154     __cow_string(__cow_string&&) noexcept;
155     __cow_string& operator=(__cow_string&&) noexcept;
156   };
157 
__cow_string()158   __cow_string::__cow_string() : _M_str() { }
159 
__cow_string(const std::string & s)160   __cow_string::__cow_string(const std::string& s) : _M_str(s) { }
161 
__cow_string(const char * s,size_t n)162   __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { }
163 
__cow_string(const __cow_string & s)164   __cow_string::__cow_string(const __cow_string& s) noexcept
165   : _M_str(s._M_str) { }
166 
167   __cow_string&
operator =(const __cow_string & s)168   __cow_string::operator=(const __cow_string& s) noexcept
169   {
170     _M_str = s._M_str;
171     return *this;
172   }
173 
~__cow_string()174   __cow_string::~__cow_string() { _M_str.~basic_string(); }
175 
__cow_string(__cow_string && s)176   __cow_string::__cow_string(__cow_string&& s) noexcept
177   : _M_str(std::move(s._M_str)) { }
178 
179   __cow_string&
operator =(__cow_string && s)180   __cow_string::operator=(__cow_string&& s) noexcept
181   {
182     _M_str = std::move(s._M_str);
183     return *this;
184   }
185 
186   static_assert(sizeof(__cow_string) == sizeof(std::string),
187                 "sizeof(std::string) has changed");
188   static_assert(alignof(__cow_string) == alignof(std::string),
189                 "alignof(std::string) has changed");
190 #endif
191 
192   // Return error_category::message() as an SSO string
193   __sso_string
_M_message(int i) const194   error_category::_M_message(int i) const
195   {
196     string msg = this->message(i);
197     return {msg.c_str(), msg.length()};
198   }
199 
200 _GLIBCXX_END_NAMESPACE_VERSION
201 } // namespace
202 
203 // Support for the Transactional Memory TS (N4514).
204 //
205 // logic_error and runtime_error both carry a message in the form of a COW
206 // string.  This COW string is never made visible to users of the exception
207 // because what() returns a C string.  The COW string can be constructed as
208 // either a copy of a COW string of another logic_error/runtime_error, or
209 // using a C string or SSO string; thus, the COW string's _Rep is only
210 // accessed by logic_error operations.  We control all txnal clones of those
211 // operations and thus can ensure that _Rep is never accessed transactionally.
212 // Furthermore, _Rep will always have been allocated or deallocated via
213 // global new or delete, so nontransactional writes we do to _Rep cannot
214 // interfere with transactional accesses.
215 
216 // We depend on having support for referencing functions declared weak that
217 // are not defined by us.  Without such support, the exceptions will not be
218 // declared transaction-safe, so we just don't provide transactional clones
219 // in this case.
220 #if _GLIBCXX_USE_WEAK_REF
221 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
222 
223 extern "C" {
224 
225 #ifndef _GLIBCXX_MANGLE_SIZE_T
226 #error Mangled name of size_t type not defined.
227 #endif
228 #define CONCAT1(x,y)		x##y
229 #define CONCAT(x,y)		CONCAT1(x,y)
230 #define _ZGTtnaX		CONCAT(_ZGTtna,_GLIBCXX_MANGLE_SIZE_T)
231 
232 #ifdef __i386__
233 /* Only for 32-bit x86.  */
234 # define ITM_REGPARM	__attribute__((regparm(2)))
235 #else
236 # define ITM_REGPARM
237 #endif
238 
239 // Declare all libitm symbols we rely on, but make them weak so that we do
240 // not depend on libitm.
241 extern void* _ZGTtnaX (size_t sz) __attribute__((weak));
242 extern void _ZGTtdlPv (void* ptr) __attribute__((weak));
243 extern uint8_t _ITM_RU1(const uint8_t *p)
244   ITM_REGPARM __attribute__((weak));
245 extern uint16_t _ITM_RU2(const uint16_t *p)
246   ITM_REGPARM __attribute__((weak));
247 extern uint32_t _ITM_RU4(const uint32_t *p)
248   ITM_REGPARM __attribute__((weak));
249 extern uint64_t _ITM_RU8(const uint64_t *p)
250   ITM_REGPARM __attribute__((weak));
251 extern void _ITM_memcpyRtWn(void *, const void *, size_t)
252   ITM_REGPARM __attribute__((weak));
253 extern void _ITM_memcpyRnWt(void *, const void *, size_t)
254   ITM_REGPARM __attribute__((weak));
255 extern void _ITM_addUserCommitAction(void (*)(void *), uint64_t, void *)
256   ITM_REGPARM __attribute__((weak));
257 
258 }
259 
260 // A transactional version of basic_string::basic_string(const char *s)
261 // that also notifies the TM runtime about allocations belonging to this
262 // exception.
263 void
_txnal_cow_string_C1_for_exceptions(void * that,const char * s,void * exc)264 _txnal_cow_string_C1_for_exceptions(void* that, const char* s,
265 				    void *exc __attribute__((unused)))
266 {
267   typedef std::basic_string<char> bs_type;
268   bs_type *bs = (bs_type*) that;
269 
270   // First, do a transactional strlen, but including the trailing zero.
271   bs_type::size_type len = 1;
272   for (const char *ss = s; _ITM_RU1((const uint8_t*) ss) != 0; ss++, len++);
273 
274 
275   // Allocate memory for the string and the refcount.  We use the
276   // transactional clone of global new[]; if this throws, it will do so in a
277   // transaction-compatible way.
278   // The allocation belongs to this exception, so tell the runtime about it.
279   // TODO Once this is supported, link the following allocation to this
280   // exception: void *prev = _ITM_setAssociatedException(exc);
281   bs_type::_Rep *rep;
282   __try
283     {
284       rep = (bs_type::_Rep*) _ZGTtnaX (len + sizeof (bs_type::_Rep));
285     }
286   __catch (...)
287     {
288       // Pop the association with this exception.
289       // TODO Once this is supported, link the following allocation to this
290       // exception: _ITM_setAssociatedException(prev);
291       // We do not need to instrument a rethrow.
292       __throw_exception_again;
293     }
294   // Pop the association with this exception.
295   // TODO Once this is supported, link the following allocation to this
296   // exception: _ITM_setAssociatedException(prev);
297 
298   // Now initialize the rest of the string and copy the C string.  The memory
299   // will be freshly allocated, so nontransactional accesses are sufficient,
300   // including the writes when copying the string (see above).
301   rep->_M_set_sharable();
302   rep->_M_length = rep->_M_capacity = len - 1;
303   _ITM_memcpyRtWn(rep->_M_refdata(), s, len);
304   new (&bs->_M_dataplus) bs_type::_Alloc_hider(rep->_M_refdata(),
305 					       bs_type::allocator_type());
306 }
307 
txnal_read_ptr(void * const * ptr)308 static void* txnal_read_ptr(void* const * ptr)
309 {
310   static_assert(sizeof(uint64_t) == sizeof(void*)
311 		|| sizeof(uint32_t) == sizeof(void*)
312 		|| sizeof(uint16_t) == sizeof(void*),
313 		"Pointers must be 16 bits, 32 bits or 64 bits wide");
314 #if __UINTPTR_MAX__ == __UINT64_MAX__
315   return (void*)_ITM_RU8((const uint64_t*)ptr);
316 #elif __UINTPTR_MAX__ == __UINT32_MAX__
317   return (void*)_ITM_RU4((const uint32_t*)ptr);
318 #else
319   return (void*)_ITM_RU2((const uint16_t*)ptr);
320 #endif
321 }
322 
323 // We must access the data pointer in the COW string transactionally because
324 // another transaction can delete the string and reuse the memory.
325 const char*
_txnal_cow_string_c_str(const void * that)326 _txnal_cow_string_c_str(const void* that)
327 {
328   typedef std::basic_string<char> bs_type;
329   const bs_type *bs = (const bs_type*) that;
330 
331   return (const char*) txnal_read_ptr((void**)&bs->_M_dataplus._M_p);
332 }
333 
334 #if _GLIBCXX_USE_DUAL_ABI
335 const char*
_txnal_sso_string_c_str(const void * that)336 _txnal_sso_string_c_str(const void* that)
337 {
338   return (const char*) txnal_read_ptr(
339       (void* const*)const_cast<char* const*>(
340 	  &((const std::__sso_string*) that)->_M_s._M_p));
341 }
342 #endif
343 
344 void
_txnal_cow_string_D1_commit(void * data)345 _txnal_cow_string_D1_commit(void* data)
346 {
347   typedef std::basic_string<char> bs_type;
348   bs_type::_Rep *rep = (bs_type::_Rep*) data;
349   rep->_M_dispose(bs_type::allocator_type());
350 }
351 
352 void
_txnal_cow_string_D1(void * that)353 _txnal_cow_string_D1(void* that)
354 {
355   typedef std::basic_string<char> bs_type;
356   bs_type::_Rep *rep = reinterpret_cast<bs_type::_Rep*>(
357       const_cast<char*>(_txnal_cow_string_c_str(that))) - 1;
358 
359   // The string can be shared, in which case we would need to decrement the
360   // reference count.  We cannot undo that because we might lose the string
361   // otherwise.  Therefore, we register a commit action that will dispose of
362   // the string's _Rep.
363   enum {_ITM_noTransactionId  = 1};
364   _ITM_addUserCommitAction(_txnal_cow_string_D1_commit, _ITM_noTransactionId,
365 			   rep);
366 }
367 
368 void*
_txnal_logic_error_get_msg(void * e)369 _txnal_logic_error_get_msg(void* e)
370 {
371   std::logic_error* le = (std::logic_error*) e;
372   return &le->_M_msg;
373 }
374 
375 void*
_txnal_runtime_error_get_msg(void * e)376 _txnal_runtime_error_get_msg(void* e)
377 {
378   std::runtime_error* le = (std::runtime_error*) e;
379   return &le->_M_msg;
380 }
381 
382 // The constructors are only declared transaction-safe if the C++11 ABI is
383 // used for std::string and the exception classes use a COW string internally.
384 // A user must not call these constructors otherwise; if they do, it will
385 // result in undefined behavior, which is in this case not initializing this
386 // string.
387 #if _GLIBCXX_USE_DUAL_ABI
388 #define CTORS_FROM_SSOSTRING(NAME, CLASS, BASE)			\
389 void									\
390 _ZGTtNSt##NAME##C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE( \
391     CLASS* that, const std::__sso_string& s)				\
392 {									\
393   CLASS e("");								\
394   _ITM_memcpyRnWt(that, &e, sizeof(CLASS));				\
395   /* Get the C string from the SSO string.  */				\
396   _txnal_cow_string_C1_for_exceptions(_txnal_##BASE##_get_msg(that),	\
397 				      _txnal_sso_string_c_str(&s), that); \
398 }									\
399 void									\
400 _ZGTtNSt##NAME##C2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE( \
401     CLASS*, const std::__sso_string&) __attribute__((alias		\
402 ("_ZGTtNSt" #NAME							\
403   "C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE")));
404 #else
405 #define CTORS_FROM_SSOSTRING(NAME, CLASS, BASE)
406 #endif
407 
408 // This macro defines transaction constructors and destructors for a specific
409 // exception class.  NAME is the variable part of the mangled name, CLASS is
410 // the class name, and BASE must be logic_error or runtime_error (which is
411 // then used to call the proper friend function that can return a pointer to
412 // the _M_msg member declared by the given (base) class).
413 #define CTORDTOR(NAME, CLASS, BASE)					\
414 void									\
415 _ZGTtNSt##NAME##C1EPKc (CLASS* that, const char* s)			\
416 {									\
417   /* This will use the singleton _Rep for an empty string and just	\
418      point to it instead of allocating memory.  Thus, we can use it as	\
419      source, copy it into the object we are constructing, and then	\
420      construct the COW string in the latter manually.  Note that the	\
421      exception classes will not be declared transaction_safe if the	\
422      shared empty _Rep is disabled with --enable-fully-dynamic-string	\
423      (in which case _GLIBCXX_FULLY_DYNAMIC_STRING is nonzero).  */	\
424   CLASS e("");								\
425   _ITM_memcpyRnWt(that, &e, sizeof(CLASS));				\
426   _txnal_cow_string_C1_for_exceptions(_txnal_##BASE##_get_msg(that),	\
427 				      s, that);				\
428 }									\
429 void									\
430 _ZGTtNSt##NAME##C2EPKc (CLASS*, const char*)				\
431   __attribute__((alias ("_ZGTtNSt" #NAME "C1EPKc")));			\
432 CTORS_FROM_SSOSTRING(NAME, CLASS, BASE)					\
433 void									\
434 _ZGTtNSt##NAME##D1Ev(CLASS* that)					\
435 { _txnal_cow_string_D1(_txnal_##BASE##_get_msg(that)); }		\
436 void									\
437 _ZGTtNSt##NAME##D2Ev(CLASS*)						\
438 __attribute__((alias ("_ZGTtNSt" #NAME "D1Ev")));			\
439 void									\
440 _ZGTtNSt##NAME##D0Ev(CLASS* that)					\
441 {									\
442   _ZGTtNSt##NAME##D1Ev(that);						\
443   _ZGTtdlPv(that);							\
444 }
445 
446 // Now create all transactional constructors and destructors, as well as the
447 // two virtual what() functions.
448 extern "C" {
449 
450 CTORDTOR(11logic_error, std::logic_error, logic_error)
451 
452 const char*
_ZGTtNKSt11logic_error4whatEv(const std::logic_error * that)453 _ZGTtNKSt11logic_error4whatEv(const std::logic_error* that)
454 {
455   return _txnal_cow_string_c_str(_txnal_logic_error_get_msg(
456       const_cast<std::logic_error*>(that)));
457 }
458 
459 CTORDTOR(12domain_error, std::domain_error, logic_error)
460 CTORDTOR(16invalid_argument, std::invalid_argument, logic_error)
461 CTORDTOR(12length_error, std::length_error, logic_error)
462 CTORDTOR(12out_of_range, std::out_of_range, logic_error)
463 
464 
465 CTORDTOR(13runtime_error, std::runtime_error, runtime_error)
466 
467 const char*
_ZGTtNKSt13runtime_error4whatEv(const std::runtime_error * that)468 _ZGTtNKSt13runtime_error4whatEv(const std::runtime_error* that)
469 {
470   return _txnal_cow_string_c_str(_txnal_runtime_error_get_msg(
471       const_cast<std::runtime_error*>(that)));
472 }
473 
474 CTORDTOR(11range_error, std::range_error, runtime_error)
475 CTORDTOR(14overflow_error, std::overflow_error, runtime_error)
476 CTORDTOR(15underflow_error, std::underflow_error, runtime_error)
477 
478 }
479 
480 #endif  // _GLIBCXX_USE_C99_STDINT_TR1
481 #endif  // _GLIBCXX_USE_WEAK_REF
482