aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-11-07 11:36:29 -0500
committerJack Lloyd <[email protected]>2016-11-07 11:43:27 -0500
commit523b2a4ca48fa5cf04ea371aabe7167ce2e5cd13 (patch)
treec9a8b736d1f7d5dfb2a0d6b31142bdf621bf1103 /src/lib/utils
parentcdadd7c77bf761e28249e7f195862082bf9e5c64 (diff)
Add CPUID::is_little_endian
Having a runtime endian test to verify against the build setting is useful.
Diffstat (limited to 'src/lib/utils')
-rw-r--r--src/lib/utils/cpuid.cpp25
-rw-r--r--src/lib/utils/cpuid.h10
2 files changed, 35 insertions, 0 deletions
diff --git a/src/lib/utils/cpuid.cpp b/src/lib/utils/cpuid.cpp
index 3fafadab7..cb25ed09d 100644
--- a/src/lib/utils/cpuid.cpp
+++ b/src/lib/utils/cpuid.cpp
@@ -8,6 +8,7 @@
#include <botan/cpuid.h>
#include <botan/types.h>
#include <botan/loadstor.h>
+#include <botan/exceptn.h>
#include <botan/mem_ops.h>
#include <ostream>
@@ -76,6 +77,7 @@ namespace Botan {
u64bit CPUID::g_processor_flags[2] = { 0, 0 };
size_t CPUID::g_cache_line_size = BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE;
bool CPUID::g_initialized = false;
+bool CPUID::g_little_endian = false;
namespace {
@@ -256,6 +258,29 @@ void CPUID::initialize()
g_processor_flags[0] = (1 << CPUID_SSE2_BIT) | (1 << CPUID_RDTSC_BIT);
#endif
+ const uint32_t endian32 = 0x01234567;
+ const uint8_t* e8 = reinterpret_cast<const uint8_t*>(&endian32);
+
+ if(e8[0] == 0x01 && e8[1] == 0x23 && e8[2] == 0x45 && e8[3] == 0x67)
+ {
+ g_little_endian = false;
+ }
+ else if(e8[0] == 0x67 && e8[1] == 0x45 && e8[2] == 0x23 && e8[3] == 0x01)
+ {
+ g_little_endian = true;
+ }
+ else
+ {
+ throw Internal_Error("Unexpected endian at runtime, neither big nor little");
+ }
+
+ // If we were compiled with a known endian, verify if matches at runtime
+#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
+ BOTAN_ASSERT(g_little_endian, "Little-endian build but big-endian at runtime");
+#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
+ BOTAN_ASSERT(!g_little_endian, "Big-endian build but little-endian at runtime");
+#endif
+
g_initialized = true;
}
diff --git a/src/lib/utils/cpuid.h b/src/lib/utils/cpuid.h
index 53e59e9e5..aa7bae963 100644
--- a/src/lib/utils/cpuid.h
+++ b/src/lib/utils/cpuid.h
@@ -42,6 +42,15 @@ class BOTAN_DLL CPUID
return g_cache_line_size;
}
+ static bool is_little_endian()
+ {
+ if(!g_initialized)
+ {
+ initialize();
+ }
+ return g_little_endian;
+ }
+
enum CPUID_bits {
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
// This matches the layout of cpuid(1)
@@ -184,6 +193,7 @@ class BOTAN_DLL CPUID
private:
static bool g_initialized;
+ static bool g_little_endian;
static size_t g_cache_line_size;
static u64bit g_processor_flags[2];
};