1// Methods for Exception Support for -*- C++ -*- 2 3// Copyright (C) 2014-2020 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 31void 32_txnal_cow_string_C1_for_exceptions(void* that, const char* s, void* exc); 33const char* 34_txnal_cow_string_c_str(const void* that); 35void 36_txnal_cow_string_D1(void* that); 37void 38_txnal_cow_string_D1_commit(void* that); 39void* 40_txnal_logic_error_get_msg(void* e); 41void* 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 52namespace 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 63 logic_error::logic_error(const logic_error& e) noexcept 64 : exception(e), _M_msg(e._M_msg) { } 65 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 75 logic_error::logic_error(logic_error&& e) noexcept 76 : exception(e), _M_msg(e._M_msg) { } 77 78 logic_error& 79 logic_error::operator=(logic_error&& e) noexcept 80 { _M_msg = e._M_msg; return *this; } 81#endif 82 83 runtime_error::runtime_error(const runtime_error& e) noexcept 84 : exception(e), _M_msg(e._M_msg) { } 85 86 runtime_error& 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 96 runtime_error::runtime_error(runtime_error&& e) noexcept 97 : exception(e), _M_msg(e._M_msg) { } 98 99 runtime_error& 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 106 logic_error::logic_error(const char* __arg) 107 : exception(), _M_msg(__arg) { } 108 109 domain_error::domain_error(const char* __arg) 110 : logic_error(__arg) { } 111 112 invalid_argument::invalid_argument(const char* __arg) 113 : logic_error(__arg) { } 114 115 length_error::length_error(const char* __arg) 116 : logic_error(__arg) { } 117 118 out_of_range::out_of_range(const char* __arg) 119 : logic_error(__arg) { } 120 121 runtime_error::runtime_error(const char* __arg) 122 : exception(), _M_msg(__arg) { } 123 124 range_error::range_error(const char* __arg) 125 : runtime_error(__arg) { } 126 127 overflow_error::overflow_error(const char* __arg) 128 : runtime_error(__arg) { } 129 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. 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 158 __cow_string::__cow_string() : _M_str() { } 159 160 __cow_string::__cow_string(const std::string& s) : _M_str(s) { } 161 162 __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { } 163 164 __cow_string::__cow_string(const __cow_string& s) noexcept 165 : _M_str(s._M_str) { } 166 167 __cow_string& 168 __cow_string::operator=(const __cow_string& s) noexcept 169 { 170 _M_str = s._M_str; 171 return *this; 172 } 173 174 __cow_string::~__cow_string() { _M_str.~basic_string(); } 175 176 __cow_string::__cow_string(__cow_string&& s) noexcept 177 : _M_str(std::move(s._M_str)) { } 178 179 __cow_string& 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 194 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 223extern "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. 241extern void* _ZGTtnaX (size_t sz) __attribute__((weak)); 242extern void _ZGTtdlPv (void* ptr) __attribute__((weak)); 243extern uint8_t _ITM_RU1(const uint8_t *p) 244 ITM_REGPARM __attribute__((weak)); 245extern uint16_t _ITM_RU2(const uint16_t *p) 246 ITM_REGPARM __attribute__((weak)); 247extern uint32_t _ITM_RU4(const uint32_t *p) 248 ITM_REGPARM __attribute__((weak)); 249extern uint64_t _ITM_RU8(const uint64_t *p) 250 ITM_REGPARM __attribute__((weak)); 251extern void _ITM_memcpyRtWn(void *, const void *, size_t) 252 ITM_REGPARM __attribute__((weak)); 253extern void _ITM_memcpyRnWt(void *, const void *, size_t) 254 ITM_REGPARM __attribute__((weak)); 255extern 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. 263void 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 308static 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. 325const char* 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 335const char* 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 344void 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 352void 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 368void* 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 375void* 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) \ 389void \ 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} \ 399void \ 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) \ 414void \ 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} \ 429void \ 430_ZGTtNSt##NAME##C2EPKc (CLASS*, const char*) \ 431 __attribute__((alias ("_ZGTtNSt" #NAME "C1EPKc"))); \ 432CTORS_FROM_SSOSTRING(NAME, CLASS, BASE) \ 433void \ 434_ZGTtNSt##NAME##D1Ev(CLASS* that) \ 435{ _txnal_cow_string_D1(_txnal_##BASE##_get_msg(that)); } \ 436void \ 437_ZGTtNSt##NAME##D2Ev(CLASS*) \ 438__attribute__((alias ("_ZGTtNSt" #NAME "D1Ev"))); \ 439void \ 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. 448extern "C" { 449 450CTORDTOR(11logic_error, std::logic_error, logic_error) 451 452const char* 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 459CTORDTOR(12domain_error, std::domain_error, logic_error) 460CTORDTOR(16invalid_argument, std::invalid_argument, logic_error) 461CTORDTOR(12length_error, std::length_error, logic_error) 462CTORDTOR(12out_of_range, std::out_of_range, logic_error) 463 464 465CTORDTOR(13runtime_error, std::runtime_error, runtime_error) 466 467const char* 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 474CTORDTOR(11range_error, std::range_error, runtime_error) 475CTORDTOR(14overflow_error, std::overflow_error, runtime_error) 476CTORDTOR(15underflow_error, std::underflow_error, runtime_error) 477 478} 479 480#endif // _GLIBCXX_USE_C99_STDINT_TR1 481#endif // _GLIBCXX_USE_WEAK_REF 482