diff options
author | Jack Lloyd <[email protected]> | 2016-11-07 11:36:29 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-11-07 11:43:27 -0500 |
commit | 523b2a4ca48fa5cf04ea371aabe7167ce2e5cd13 (patch) | |
tree | c9a8b736d1f7d5dfb2a0d6b31142bdf621bf1103 | |
parent | cdadd7c77bf761e28249e7f195862082bf9e5c64 (diff) |
Add CPUID::is_little_endian
Having a runtime endian test to verify against the build setting is
useful.
-rw-r--r-- | src/lib/utils/cpuid.cpp | 25 | ||||
-rw-r--r-- | src/lib/utils/cpuid.h | 10 |
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]; }; |