aboutsummaryrefslogtreecommitdiff
path: root/src/compat
diff options
context:
space:
mode:
Diffstat (limited to 'src/compat')
-rw-r--r--src/compat/glibc_compat.cpp19
-rw-r--r--src/compat/glibc_sanity.cpp67
-rw-r--r--src/compat/glibcxx_compat.cpp50
-rw-r--r--src/compat/glibcxx_sanity.cpp65
-rw-r--r--src/compat/sanity.h11
5 files changed, 185 insertions, 27 deletions
diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp
index 5b73e6051a..22f82e4259 100644
--- a/src/compat/glibc_compat.cpp
+++ b/src/compat/glibc_compat.cpp
@@ -1,19 +1,28 @@
-#include "bitcoin-config.h"
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
#include <cstddef>
+#if defined(HAVE_SYS_SELECT_H)
#include <sys/select.h>
+#endif
// Prior to GLIBC_2.14, memcpy was aliased to memmove.
extern "C" void* memmove(void* a, const void* b, size_t c);
extern "C" void* memcpy(void* a, const void* b, size_t c)
{
- return memmove(a, b, c);
+ return memmove(a, b, c);
}
extern "C" void __chk_fail (void) __attribute__((__noreturn__));
extern "C" FDELT_TYPE __fdelt_warn(FDELT_TYPE a)
{
- if (a >= FD_SETSIZE)
- __chk_fail ();
- return a / __NFDBITS;
+ if (a >= FD_SETSIZE)
+ __chk_fail ();
+ return a / __NFDBITS;
}
extern "C" FDELT_TYPE __fdelt_chk(FDELT_TYPE) __attribute__((weak, alias("__fdelt_warn")));
diff --git a/src/compat/glibc_sanity.cpp b/src/compat/glibc_sanity.cpp
new file mode 100644
index 0000000000..d93602e0fe
--- /dev/null
+++ b/src/compat/glibc_sanity.cpp
@@ -0,0 +1,67 @@
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <cstddef>
+#if defined(HAVE_SYS_SELECT_H)
+#include <sys/select.h>
+#endif
+
+extern "C" void* memcpy(void* a, const void* b, size_t c);
+void* memcpy_int(void* a, const void* b, size_t c)
+{
+ return memcpy(a,b,c);
+}
+
+namespace {
+// trigger: Use the memcpy_int wrapper which calls our internal memcpy.
+// A direct call to memcpy may be optimized away by the compiler.
+// test: Fill an array with a sequence of integers. memcpy to a new empty array.
+// Verify that the arrays are equal. Use an odd size to decrease the odds of
+// the call being optimized away.
+template <unsigned int T>
+bool sanity_test_memcpy()
+{
+ unsigned int memcpy_test[T];
+ unsigned int memcpy_verify[T] = {};
+ for (unsigned int i = 0; i != T; ++i)
+ memcpy_test[i] = i;
+
+ memcpy_int(memcpy_verify,memcpy_test,sizeof(memcpy_test));
+
+ for (unsigned int i = 0; i != T; ++i)
+ {
+ if(memcpy_verify[i] != i)
+ return false;
+ }
+ return true;
+}
+
+#if defined(HAVE_SYS_SELECT_H)
+// trigger: Call FD_SET to trigger __fdelt_chk. FORTIFY_SOURCE must be defined
+// as >0 and optimizations must be set to at least -O2.
+// test: Add a file descriptor to an empty fd_set. Verify that it has been
+// correctly added.
+bool sanity_test_fdelt()
+{
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(0, &fds);
+ return FD_ISSET(0,&fds);
+}
+#endif
+
+} // anon namespace
+
+bool glibc_sanity_test()
+{
+#if defined(HAVE_SYS_SELECT_H)
+ if (!sanity_test_fdelt())
+ return false;
+#endif
+ return sanity_test_memcpy<1025>();
+}
diff --git a/src/compat/glibcxx_compat.cpp b/src/compat/glibcxx_compat.cpp
index e91376f818..417166aeda 100644
--- a/src/compat/glibcxx_compat.cpp
+++ b/src/compat/glibcxx_compat.cpp
@@ -1,49 +1,55 @@
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
#include <cstddef>
#include <istream>
#include <stdexcept>
#include <typeinfo>
#ifndef _GLIBCXX_USE_NOEXCEPT
- #define _GLIBCXX_USE_NOEXCEPT throw()
+#define _GLIBCXX_USE_NOEXCEPT throw()
#endif
namespace std {
const char* bad_exception::what() const throw()
{
- return "std::bad_exception";
+ return "std::bad_exception";
}
const char* bad_cast::what() const throw()
{
- return "std::bad_cast";
+ return "std::bad_cast";
}
const char* bad_alloc::what() const throw()
{
- return "std::bad_alloc";
+ return "std::bad_alloc";
}
namespace __detail
{
struct _List_node_base
{
- void _M_hook(std::__detail::_List_node_base* const __position) throw () __attribute__((used))
- {
- _M_next = __position;
- _M_prev = __position->_M_prev;
- __position->_M_prev->_M_next = this;
- __position->_M_prev = this;
- }
- void _M_unhook() __attribute__((used))
- {
- _List_node_base* const __next_node = _M_next;
- _List_node_base* const __prev_node = _M_prev;
- __prev_node->_M_next = __next_node;
- __next_node->_M_prev = __prev_node;
- }
- _List_node_base* _M_next;
- _List_node_base* _M_prev;
+ void _M_hook(std::__detail::_List_node_base* const __position) throw () __attribute__((used))
+ {
+ _M_next = __position;
+ _M_prev = __position->_M_prev;
+ __position->_M_prev->_M_next = this;
+ __position->_M_prev = this;
+ }
+
+ void _M_unhook() __attribute__((used))
+ {
+ _List_node_base* const __next_node = _M_next;
+ _List_node_base* const __prev_node = _M_prev;
+ __prev_node->_M_next = __next_node;
+ __next_node->_M_prev = __prev_node;
+ }
+
+ _List_node_base* _M_next;
+ _List_node_base* _M_prev;
};
} // namespace detail
@@ -61,8 +67,8 @@ out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
// Used with permission.
// See: https://github.com/madlib/madlib/commit/c3db418c0d34d6813608f2137fef1012ce03043d
-void
-ctype<char>::_M_widen_init() const {
+void ctype<char>::_M_widen_init() const
+{
char __tmp[sizeof(_M_widen)];
for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
__tmp[__i] = __i;
diff --git a/src/compat/glibcxx_sanity.cpp b/src/compat/glibcxx_sanity.cpp
new file mode 100644
index 0000000000..cd8da4fd67
--- /dev/null
+++ b/src/compat/glibcxx_sanity.cpp
@@ -0,0 +1,65 @@
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <list>
+#include <locale>
+#include <stdexcept>
+
+namespace{
+
+// trigger: use ctype<char>::widen to trigger ctype<char>::_M_widen_init().
+// test: convert a char from narrow to wide and back. Verify that the result
+// matches the original.
+bool sanity_test_widen(char testchar)
+{
+ const std::ctype<char>& test(std::use_facet< std::ctype<char> >(std::locale()));
+ return test.narrow(test.widen(testchar),'b') == testchar;
+}
+
+// trigger: use list::push_back and list::pop_back to trigger _M_hook and
+// _M_unhook.
+// test: Push a sequence of integers into a list. Pop them off and verify that
+// they match the original sequence.
+bool sanity_test_list(unsigned int size)
+{
+ std::list<unsigned int> test;
+ for (unsigned int i = 0; i != size; ++i)
+ test.push_back(i+1);
+
+ if (test.size() != size)
+ return false;
+
+ while (!test.empty())
+ {
+ if(test.back() != test.size())
+ return false;
+ test.pop_back();
+ }
+ return true;
+}
+
+} // anon namespace
+
+// trigger: string::at(x) on an empty string to trigger __throw_out_of_range_fmt.
+// test: force std::string to throw an out_of_range exception. Verify that
+// it's caught correctly.
+bool sanity_test_range_fmt()
+{
+ std::string test;
+ try
+ {
+ test.at(1);
+ }
+ catch (const std::out_of_range&)
+ {
+ return true;
+ }
+ catch (...){}
+ return false;
+}
+
+bool glibcxx_sanity_test()
+{
+ return sanity_test_widen('a') && sanity_test_list(100) && sanity_test_range_fmt();
+}
diff --git a/src/compat/sanity.h b/src/compat/sanity.h
new file mode 100644
index 0000000000..e7df44307a
--- /dev/null
+++ b/src/compat/sanity.h
@@ -0,0 +1,11 @@
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCON_COMPAT_SANITY_H
+#define BITCON_COMPAT_SANITY_H
+
+bool glibc_sanity_test();
+bool glibcxx_sanity_test();
+
+#endif // BITCON_COMPAT_SANITY_H