diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc
index ca71e57e4e0..c8fc07ff269 100644
--- a/libstdc++-v3/include/bits/regex_compiler.tcc
+++ b/libstdc++-v3/include/bits/regex_compiler.tcc
@@ -55,6 +55,8 @@
 // All dummy nodes will be eliminated at the end of compilation.
 */
 
+#define __EXCSTR(s) (__extension__({static const char __exception_what__[] __attribute__((section(".irom.exceptiontext,\"MS\",@progbits,1#"))) = (s); &__exception_what__[0];}))
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -165,7 +167,7 @@ namespace __detail
 	  this->_M_disjunction();
 	  if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
 	    __throw_regex_error(regex_constants::error_paren,
-				"Parenthesis is not closed.");
+				__EXCSTR("Parenthesis is not closed."));
 	  auto __tmp = _M_pop();
 	  __tmp._M_append(_M_nfa->_M_insert_accept());
 	  _M_stack.push(
@@ -188,7 +190,7 @@ namespace __detail
 	{
 	  if (_M_stack.empty())
 	    __throw_regex_error(regex_constants::error_badrepeat,
-				"Nothing to repeat before a quantifier.");
+				__EXCSTR("Nothing to repeat before a quantifier."));
 	  __neg = __neg && _M_match_token(_ScannerT::_S_token_opt);
 	};
       if (_M_match_token(_ScannerT::_S_token_closure0))
@@ -225,10 +227,10 @@ namespace __detail
 	{
 	  if (_M_stack.empty())
 	    __throw_regex_error(regex_constants::error_badrepeat,
-				"Nothing to repeat before a quantifier.");
+				__EXCSTR("Nothing to repeat before a quantifier."));
 	  if (!_M_match_token(_ScannerT::_S_token_dup_count))
 	    __throw_regex_error(regex_constants::error_badbrace,
-				"Unexpected token in brace expression.");
+				__EXCSTR("Unexpected token in brace expression."));
 	  _StateSeqT __r(_M_pop());
 	  _StateSeqT __e(*_M_nfa, _M_nfa->_M_insert_dummy());
 	  long __min_rep = _M_cur_int_value(10);
@@ -245,7 +247,7 @@ namespace __detail
 	    __n = 0;
 	  if (!_M_match_token(_ScannerT::_S_token_interval_end))
 	    __throw_regex_error(regex_constants::error_brace,
-				"Unexpected end of brace expression.");
+				__EXCSTR("Unexpected end of brace expression."));
 
 	  __neg = __neg && _M_match_token(_ScannerT::_S_token_opt);
 
@@ -265,7 +267,7 @@ namespace __detail
 	    {
 	      if (__n < 0)
 		__throw_regex_error(regex_constants::error_badbrace,
-				    "Invalid range in brace expression.");
+				    __EXCSTR("Invalid range in brace expression."));
 	      auto __end = _M_nfa->_M_insert_dummy();
 	      // _M_alt is the "match more" branch, and _M_next is the
 	      // "match less" one. Switch _M_alt and _M_next of all created
@@ -333,7 +335,7 @@ namespace __detail
 	  this->_M_disjunction();
 	  if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
 	    __throw_regex_error(regex_constants::error_paren,
-				"Parenthesis is not closed.");
+				__EXCSTR("Parenthesis is not closed."));
 	  __r._M_append(_M_pop());
 	  _M_stack.push(__r);
 	}
@@ -343,7 +345,7 @@ namespace __detail
 	  this->_M_disjunction();
 	  if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
 	    __throw_regex_error(regex_constants::error_paren,
-				"Parenthesis is not closed.");
+				__EXCSTR("Parenthesis is not closed."));
 	  __r._M_append(_M_pop());
 	  __r._M_append(_M_nfa->_M_insert_subexpr_end());
 	  _M_stack.push(__r);
@@ -519,9 +521,9 @@ namespace __detail
 		    }
 		  __throw_regex_error(
 		    regex_constants::error_range,
-		    "Unexpected dash in bracket expression. For POSIX syntax, "
+		    __EXCSTR("Unexpected dash in bracket expression. For POSIX syntax, "
 		    "a dash is not treated literally only when it is at "
-		    "beginning or end.");
+		    "beginning or end."));
 		}
 	      __push_char('-');
 	    }
@@ -543,7 +545,7 @@ namespace __detail
 		      != _ScannerT::_S_token_bracket_end)
 		    __throw_regex_error(
 		      regex_constants::error_range,
-		      "Character is expected after a dash.");
+		      __EXCSTR("Character is expected after a dash."));
 		  __push_char('-');
 		}
 	    }
@@ -557,7 +559,7 @@ namespace __detail
 	}
       else
 	__throw_regex_error(regex_constants::error_brack,
-			    "Unexpected character in bracket expression.");
+			    __EXCSTR("Unexpected character in bracket expression."));
 
       return true;
     }
@@ -639,3 +641,5 @@ namespace __detail
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#undef __EXCSTR
diff --git a/libstdc++-v3/include/bits/regex_automaton.h b/libstdc++-v3/include/bits/regex_automaton.h
index e5e184b5678..c0f7304452d 100644
--- a/libstdc++-v3/include/bits/regex_automaton.h
+++ b/libstdc++-v3/include/bits/regex_automaton.h
@@ -33,6 +33,9 @@
 #define _GLIBCXX_REGEX_STATE_LIMIT 100000
 #endif
 
+#define __EXCSTR(s) (__extension__({static const char __exception_what__[] __attribute__((section(".irom.exceptiontext,\"MS\",@progbits,1#"))) = (s); &__exception_what__[0];}))
+
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -330,9 +333,9 @@ namespace __detail
 	if (this->size() > _GLIBCXX_REGEX_STATE_LIMIT)
 	  __throw_regex_error(
 	    regex_constants::error_space,
-	    "Number of NFA states exceeds limit. Please use shorter regex "
+	    __EXCSTR("Number of NFA states exceeds limit. Please use shorter regex "
 	    "string, or use smaller brace expression, or make "
-	    "_GLIBCXX_REGEX_STATE_LIMIT larger.");
+	    "_GLIBCXX_REGEX_STATE_LIMIT larger."));
 	return this->size() - 1;
       }
 
@@ -398,4 +401,6 @@ namespace __detail
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
+#undef __EXCSTR
+
 #include <bits/regex_automaton.tcc>
diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h
index 45a24a6b740..045f399d57f 100644
--- a/libstdc++-v3/include/bits/regex_compiler.h
+++ b/libstdc++-v3/include/bits/regex_compiler.h
@@ -28,6 +28,8 @@
  *  Do not attempt to use it directly. @headername{regex}
  */
 
+#define __EXCSTR(s) (__extension__({static const char __exception_what__[] __attribute__((section(".irom.exceptiontext,\"MS\",@progbits,1#"))) = (s); &__exception_what__[0];}))
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -447,7 +449,7 @@ namespace __detail
 						 __s.data() + __s.size());
 	if (__st.empty())
 	  __throw_regex_error(regex_constants::error_collate,
-			      "Invalid collate element.");
+			      __EXCSTR("Invalid collate element."));
 	_M_char_set.push_back(_M_translator._M_translate(__st[0]));
 	_GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
 	return __st;
@@ -460,7 +462,7 @@ namespace __detail
 						 __s.data() + __s.size());
 	if (__st.empty())
 	  __throw_regex_error(regex_constants::error_collate,
-			      "Invalid equivalence class.");
+			      __EXCSTR("Invalid equivalence class."));
 	__st = _M_traits.transform_primary(__st.data(),
 					   __st.data() + __st.size());
 	_M_equiv_set.push_back(__st);
@@ -476,7 +478,7 @@ namespace __detail
 						 __icase);
 	if (__mask == 0)
 	  __throw_regex_error(regex_constants::error_collate,
-			      "Invalid character class.");
+			      __EXCSTR("Invalid character class."));
 	if (!__neg)
 	  _M_class_set |= __mask;
 	else
@@ -489,7 +491,7 @@ namespace __detail
       {
 	if (__l > __r)
 	  __throw_regex_error(regex_constants::error_range,
-			      "Invalid range in bracket expression.");
+			      __EXCSTR("Invalid range in bracket expression."));
 	_M_range_set.push_back(make_pair(_M_translator._M_transform(__l),
 					 _M_translator._M_transform(__r)));
 	_GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
@@ -557,4 +559,6 @@ namespace __detail
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
+#undef __EXCSTR
+
 #include <bits/regex_compiler.tcc>
diff --git a/libstdc++-v3/include/bits/regex_scanner.tcc b/libstdc++-v3/include/bits/regex_scanner.tcc
index cb40602b40f..8118bb88b87 100644
--- a/libstdc++-v3/include/bits/regex_scanner.tcc
+++ b/libstdc++-v3/include/bits/regex_scanner.tcc
@@ -46,6 +46,8 @@
 //
 // awk: http://pubs.opengroup.org/onlinepubs/000095399/utilities/awk.html
 
+#define __EXCSTR(s) (__extension__({static const char __exception_what__[] __attribute__((section(".irom.exceptiontext,\"MS\",@progbits,1#"))) = (s); &__exception_what__[0];}))
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -109,7 +111,7 @@ namespace __detail
 	  if (_M_current == _M_end)
 	    __throw_regex_error(
 	      regex_constants::error_escape,
-	      "Unexpected end of regex when escaping.");
+	      __EXCSTR("Unexpected end of regex when escaping."));
 
 	  if (!_M_is_basic()
 	      || (*_M_current != '('
@@ -128,7 +130,7 @@ namespace __detail
 	      if (++_M_current == _M_end)
 		__throw_regex_error(
 		  regex_constants::error_paren,
-		  "Unexpected end of regex when in an open parenthesis.");
+		  __EXCSTR("Unexpected end of regex when in an open parenthesis."));
 
 	      if (*_M_current == ':')
 		{
@@ -150,7 +152,7 @@ namespace __detail
 	      else
 		__throw_regex_error(
 		  regex_constants::error_paren,
-		  "Invalid special open parenthesis.");
+		  __EXCSTR("Invalid special open parenthesis."));
 	    }
 	  else if (_M_flags & regex_constants::nosubs)
 	    _M_token = _S_token_subexpr_no_group_begin;
@@ -206,7 +208,7 @@ namespace __detail
       if (_M_current == _M_end)
 	__throw_regex_error(
 	  regex_constants::error_brack,
-	  "Unexpected end of regex when in bracket expression.");
+	  __EXCSTR("Unexpected end of regex when in bracket expression."));
 
       auto __c = *_M_current++;
 
@@ -216,7 +218,7 @@ namespace __detail
 	{
 	  if (_M_current == _M_end)
 	    __throw_regex_error(regex_constants::error_brack,
-				"Unexpected character class open bracket.");
+				__EXCSTR("Unexpected character class open bracket."));
 
 	  if (*_M_current == '.')
 	    {
@@ -268,7 +270,7 @@ namespace __detail
       if (_M_current == _M_end)
 	__throw_regex_error(
 	  regex_constants::error_brace,
-	  "Unexpected end of regex when in brace expression.");
+	  __EXCSTR("Unexpected end of regex when in brace expression."));
 
       auto __c = *_M_current++;
 
@@ -293,7 +295,7 @@ namespace __detail
 	    }
 	  else
 	    __throw_regex_error(regex_constants::error_badbrace,
-				"Unexpected character in brace expression.");
+				__EXCSTR("Unexpected character in brace expression."));
 	}
       else if (__c == '}')
 	{
@@ -302,7 +304,7 @@ namespace __detail
 	}
       else
 	__throw_regex_error(regex_constants::error_badbrace,
-			    "Unexpected character in brace expression.");
+			    __EXCSTR("Unexpected character in brace expression."));
     }
 
   template<typename _CharT>
@@ -312,7 +314,7 @@ namespace __detail
     {
       if (_M_current == _M_end)
 	__throw_regex_error(regex_constants::error_escape,
-			    "Unexpected end of regex when escaping.");
+			    __EXCSTR("Unexpected end of regex when escaping."));
 
       auto __c = *_M_current++;
       auto __pos = _M_find_escape(_M_ctype.narrow(__c, '\0'));
@@ -348,7 +350,7 @@ namespace __detail
 	  if (_M_current == _M_end)
 	    __throw_regex_error(
 	      regex_constants::error_escape,
-	      "Unexpected end of regex when reading control code.");
+	      __EXCSTR("Unexpected end of regex when reading control code."));
 	  _M_token = _S_token_ord_char;
 	  _M_value.assign(1, *_M_current++);
 	}
@@ -361,7 +363,7 @@ namespace __detail
 		  || !_M_ctype.is(_CtypeT::xdigit, *_M_current))
 		__throw_regex_error(
 		  regex_constants::error_escape,
-		  "Unexpected end of regex when ascii character.");
+		  __EXCSTR("Unexpected end of regex when ascii character."));
 	      _M_value += *_M_current++;
 	    }
 	  _M_token = _S_token_hex_num;
@@ -391,7 +393,7 @@ namespace __detail
     {
       if (_M_current == _M_end)
 	__throw_regex_error(regex_constants::error_escape,
-			    "Unexpected end of regex when escaping.");
+			    __EXCSTR("Unexpected end of regex when escaping."));
 
       auto __c = *_M_current;
       auto __pos = std::strchr(_M_spec_char, _M_ctype.narrow(__c, '\0'));
@@ -417,7 +419,7 @@ namespace __detail
 #ifdef __STRICT_ANSI__
 	  // POSIX says it is undefined to escape ordinary characters
 	  __throw_regex_error(regex_constants::error_escape,
-			      "Unexpected escape character.");
+			      __EXCSTR("Unexpected escape character."));
 #else
 	  _M_token = _S_token_ord_char;
 	  _M_value.assign(1, __c);
@@ -458,7 +460,7 @@ namespace __detail
 	}
       else
 	__throw_regex_error(regex_constants::error_escape,
-			    "Unexpected escape character.");
+			    __EXCSTR("Unexpected escape character."));
     }
 
   // Eats a character class or throws an exception.
@@ -478,10 +480,10 @@ namespace __detail
 	{
 	  if (__ch == ':')
 	    __throw_regex_error(regex_constants::error_ctype,
-				"Unexpected end of character class.");
+				__EXCSTR("Unexpected end of character class."));
 	  else
 	    __throw_regex_error(regex_constants::error_collate,
-				"Unexpected end of character class.");
+				__EXCSTR("Unexpected end of character class."));
 	}
     }
 
@@ -587,3 +589,5 @@ namespace __detail
 } // namespace __detail
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
+
+#undef __EXCSTR
