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