forked from devyte/esp-quick-toolchain
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enable PROGMEM safe handlers in exceptions for 4.8
- Loading branch information
1 parent
e44a7c6
commit b40a506
Showing
4 changed files
with
263 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
diff --git a/libstdc++-v3/config/os/newlib/ctype_inline.h b/libstdc++-v3/config/os/newlib/ctype_inline.h | ||
index a4714f9bcce..479ceef7191 100644 | ||
--- a/libstdc++-v3/config/os/newlib/ctype_inline.h | ||
+++ b/libstdc++-v3/config/os/newlib/ctype_inline.h | ||
@@ -34,6 +34,26 @@ | ||
// ctype bits to be inlined go here. Non-inlinable (ie virtual do_*) | ||
// functions go in ctype.cc | ||
|
||
+#ifndef __ctype__pgm_read_with_offset | ||
+ | ||
+#define __ctype__pgm_read_with_offset(addr, res) \ | ||
+ asm("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \ | ||
+ "sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \ | ||
+ "l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ \ | ||
+ "ssa8l %0\n" /* Prepare to shift by offset (in bits) */ \ | ||
+ "src %0, %1, %1\n" /* Shift right; now the requested byte is the first one */ \ | ||
+ :"=r"(res), "=r"(addr) \ | ||
+ :"1"(addr) \ | ||
+:); | ||
+ | ||
+static inline uint8_t __ctype__pgm_read_byte_inlined(const void* addr) { | ||
+ register uint32_t res; | ||
+ __ctype__pgm_read_with_offset(addr, res); | ||
+ return (uint8_t) res; /* This masks the lower byte from the returned word */ | ||
+} | ||
+ | ||
+#endif | ||
+ | ||
namespace std _GLIBCXX_VISIBILITY(default) | ||
{ | ||
_GLIBCXX_BEGIN_NAMESPACE_VERSION | ||
@@ -41,14 +61,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION | ||
bool | ||
ctype<char>:: | ||
is(mask __m, char __c) const | ||
- { return _M_table[static_cast<unsigned char>(__c)] & __m; } | ||
+ { return __ctype__pgm_read_byte_inlined(&_M_table[static_cast<unsigned char>(__c)]) & __m; } | ||
|
||
const char* | ||
ctype<char>:: | ||
is(const char* __low, const char* __high, mask* __vec) const | ||
{ | ||
while (__low < __high) | ||
- *__vec++ = _M_table[static_cast<unsigned char>(*__low++)]; | ||
+ *__vec++ = __ctype__pgm_read_byte_inlined(&_M_table[static_cast<unsigned char>(*__low++)]); | ||
return __high; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in | ||
index ea390a5bbea..9268851c44a 100644 | ||
--- a/libgcc/Makefile.in | ||
+++ b/libgcc/Makefile.in | ||
@@ -851,7 +851,7 @@ endif | ||
# libgcc_eh.a, only LIB2ADDEH matters. If we do, only LIB2ADDEHSTATIC and | ||
# LIB2ADDEHSHARED matter. (Usually all three are identical.) | ||
|
||
-c_flags := -fexceptions | ||
+c_flags := -fexceptions -mforce-l32 | ||
|
||
ifeq ($(enable_shared),yes) | ||
|
||
@@ -874,7 +874,7 @@ endif | ||
# Build LIBUNWIND. Use -fno-exceptions so that the unwind library does | ||
# not generate calls to __gcc_personality_v0. | ||
|
||
-c_flags := -fno-exceptions | ||
+c_flags := -fno-exceptions -mforce-l32 | ||
|
||
libunwind-objects += $(addsuffix $(objext),$(basename $(notdir $(LIBUNWIND)))) | ||
|
||
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in | ||
index 8bf86f35af6..b6adcc7ab49 100644 | ||
--- a/libstdc++-v3/libsupc++/Makefile.in | ||
+++ b/libstdc++-v3/libsupc++/Makefile.in | ||
@@ -335,7 +335,7 @@ toolexeclibdir = $(glibcxx_toolexeclibdir) | ||
# These bits are all figured out from configure. Look in acinclude.m4 | ||
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS. | ||
CONFIG_CXXFLAGS = \ | ||
- $(SECTION_FLAGS) $(HWCAP_FLAGS) -frandom-seed=$@ | ||
+ $(SECTION_FLAGS) $(HWCAP_FLAGS) -frandom-seed=$@ -mforce-l32 | ||
|
||
WARN_CXXFLAGS = \ | ||
$(WARN_FLAGS) $(WERROR_FLAG) -fdiagnostics-show-location=once |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
diff --git a/libstdc++-v3/libsupc++/tinfo.cc b/libstdc++-v3/libsupc++/tinfo.cc | ||
index f10e270b6ae..3fcac0469a4 100644 | ||
--- a/libstdc++-v3/libsupc++/tinfo.cc | ||
+++ b/libstdc++-v3/libsupc++/tinfo.cc | ||
@@ -26,6 +26,22 @@ | ||
#include <cstddef> | ||
#include "tinfo.h" | ||
|
||
+ // Write own version so it's compiled with mforce-l32 and won't crash | ||
+static int strcmp_safe(const char *p1, const char *p2) { | ||
+ const unsigned char *s1 = (const unsigned char *) p1; | ||
+ const unsigned char *s2 = (const unsigned char *) p2; | ||
+ unsigned char c1, c2; | ||
+ do | ||
+ { | ||
+ c1 = (unsigned char) *s1++; | ||
+ c2 = (unsigned char) *s2++; | ||
+ if (c1 == '\0') | ||
+ return c1 - c2; | ||
+ } | ||
+ while (c1 == c2); | ||
+ return c1 - c2; | ||
+ } | ||
+ | ||
std::type_info:: | ||
~type_info () | ||
{ } | ||
@@ -43,7 +59,7 @@ operator== (const std::type_info& arg) const _GLIBCXX_NOEXCEPT | ||
take care to look at __name rather than name() when looking for | ||
the "pointer" prefix. */ | ||
return (&arg == this) | ||
- || (__name[0] != '*' && (__builtin_strcmp (name (), arg.name ()) == 0)); | ||
+ || (__name[0] != '*' && (strcmp_safe (name (), arg.name ()) == 0)); | ||
#endif | ||
} | ||
|
||
diff --git a/libstdc++-v3/libsupc++/tinfo2.cc b/libstdc++-v3/libsupc++/tinfo2.cc | ||
index 533824ca032..545df820fb6 100644 | ||
--- a/libstdc++-v3/libsupc++/tinfo2.cc | ||
+++ b/libstdc++-v3/libsupc++/tinfo2.cc | ||
@@ -29,6 +29,21 @@ | ||
using std::type_info; | ||
|
||
#if !__GXX_TYPEINFO_EQUALITY_INLINE | ||
+ // Write own version so it's compiled with mforce-l32 and won't crash | ||
+static int strcmp_safe(const char *p1, const char *p2) { | ||
+ const unsigned char *s1 = (const unsigned char *) p1; | ||
+ const unsigned char *s2 = (const unsigned char *) p2; | ||
+ unsigned char c1, c2; | ||
+ do | ||
+ { | ||
+ c1 = (unsigned char) *s1++; | ||
+ c2 = (unsigned char) *s2++; | ||
+ if (c1 == '\0') | ||
+ return c1 - c2; | ||
+ } | ||
+ while (c1 == c2); | ||
+ return c1 - c2; | ||
+ } | ||
|
||
bool | ||
type_info::before (const type_info &arg) const _GLIBCXX_NOEXCEPT | ||
@@ -37,7 +52,7 @@ type_info::before (const type_info &arg) const _GLIBCXX_NOEXCEPT | ||
return name () < arg.name (); | ||
#else | ||
return (name ()[0] == '*') ? name () < arg.name () | ||
- : __builtin_strcmp (name (), arg.name ()) < 0; | ||
+ : strcmp_safe (name (), arg.name ()) < 0; | ||
#endif | ||
} | ||
|
||
diff --git a/libstdc++-v3/libsupc++/typeinfo b/libstdc++-v3/libsupc++/typeinfo | ||
index 0ed47fcdfb6..345c95b3270 100644 | ||
--- a/libstdc++-v3/libsupc++/typeinfo | ||
+++ b/libstdc++-v3/libsupc++/typeinfo | ||
@@ -50,7 +50,7 @@ namespace __cxxabiv1 | ||
// must be compared), and whether comparison is to be implemented inline or | ||
// not. We used to do inline pointer comparison by default if weak symbols | ||
// are available, but even with weak symbols sometimes names are not merged | ||
-// when objects are loaded with RTLD_LOCAL, so now we always use strcmp by | ||
+// when objects are loaded with RTLD_LOCAL, so now we always use p2 by | ||
// default. For ABI compatibility, we do the strcmp inline if weak symbols | ||
// are available, and out-of-line if not. Out-of-line pointer comparison | ||
// is used where the object files are to be portable to multiple systems, | ||
@@ -115,13 +115,13 @@ namespace std | ||
bool before(const type_info& __arg) const _GLIBCXX_NOEXCEPT | ||
{ return (__name[0] == '*' && __arg.__name[0] == '*') | ||
? __name < __arg.__name | ||
- : __builtin_strcmp (__name, __arg.__name) < 0; } | ||
+ : strcmp_safe (__name, __arg.__name) < 0; } | ||
|
||
bool operator==(const type_info& __arg) const _GLIBCXX_NOEXCEPT | ||
{ | ||
return ((__name == __arg.__name) | ||
|| (__name[0] != '*' && | ||
- __builtin_strcmp (__name, __arg.__name) == 0)); | ||
+ strcmp_safe (__name, __arg.__name) == 0)); | ||
} | ||
#else | ||
// On some targets we can rely on type_info's NTBS being unique, | ||
@@ -176,6 +176,23 @@ namespace std | ||
/// Assigning type_info is not supported. | ||
type_info& operator=(const type_info&); | ||
type_info(const type_info&); | ||
+ | ||
+ // Write own version so it's compiled with mforce-l32 and won't crash | ||
+ static int strcmp_safe(const char *p1, const char *p2) { | ||
+ const unsigned char *s1 = (const unsigned char *) p1; | ||
+ const unsigned char *s2 = (const unsigned char *) p2; | ||
+ unsigned char c1, c2; | ||
+ do | ||
+ { | ||
+ c1 = (unsigned char) *s1++; | ||
+ c2 = (unsigned char) *s2++; | ||
+ if (c1 == '\0') | ||
+ return c1 - c2; | ||
+ } | ||
+ while (c1 == c2); | ||
+ return c1 - c2; | ||
+ } | ||
+ | ||
}; | ||
|
||
/** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c | ||
index 24b4ecee68c..56328c47e1e 100644 | ||
--- a/libgcc/unwind-dw2-fde.c | ||
+++ b/libgcc/unwind-dw2-fde.c | ||
@@ -285,6 +285,15 @@ base_from_object (unsigned char encoding, struct object *ob) | ||
} | ||
} | ||
|
||
+ | ||
+// Write own version so it's compiled with mforce-l32 and won't crash | ||
+static size_t strlen_safe(const char *s) { | ||
+ size_t len = 0; | ||
+ while(*s++) len++; | ||
+ return len; | ||
+} | ||
+ | ||
+ | ||
/* Return the FDE pointer encoding from the CIE. */ | ||
/* ??? This is a subset of extract_cie_info from unwind-dw2.c. */ | ||
|
||
@@ -297,7 +306,7 @@ get_cie_encoding (const struct dwarf_cie *cie) | ||
_sleb128_t stmp; | ||
|
||
aug = cie->augmentation; | ||
- p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string. */ | ||
+ p = aug + strlen_safe ((const char *)aug) + 1; /* Skip the augmentation string. */ | ||
if (__builtin_expect (cie->version >= 4, 0)) | ||
{ | ||
if (p[0] != sizeof (void *) || p[1] != 0) | ||
diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c | ||
index e6130af2fb5..f2bd0ba454e 100644 | ||
--- a/libgcc/unwind-dw2.c | ||
+++ b/libgcc/unwind-dw2.c | ||
@@ -410,6 +410,13 @@ _Unwind_GetTextRelBase (struct _Unwind_Context *context) | ||
|
||
#include "md-unwind-support.h" | ||
|
||
+// Write own version so it's compiled with mforce-l32 and won't crash | ||
+static size_t strlen_safe(const char *s) { | ||
+ size_t len = 0; | ||
+ while(*s++) len++; | ||
+ return len; | ||
+} | ||
+ | ||
/* Extract any interesting information from the CIE for the translation | ||
unit F belongs to. Return a pointer to the byte after the augmentation, | ||
or NULL if we encountered an undecipherable augmentation. */ | ||
@@ -419,7 +426,7 @@ extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context, | ||
_Unwind_FrameState *fs) | ||
{ | ||
const unsigned char *aug = cie->augmentation; | ||
- const unsigned char *p = aug + strlen ((const char *)aug) + 1; | ||
+ const unsigned char *p = aug + strlen_safe ((const char *)aug) + 1; | ||
const unsigned char *ret = NULL; | ||
_uleb128_t utmp; | ||
_sleb128_t stmp; |