diff options
author | Cory Fields <cory-nospam-@coryfields.com> | 2017-06-16 14:43:35 -0400 |
---|---|---|
committer | Cory Fields <cory-nospam-@coryfields.com> | 2017-06-16 15:19:15 -0400 |
commit | 9af207c810b5c4b09ccbdec75582b3e34e32e8cc (patch) | |
tree | cb558fe7015607bb55bcd3b0f9619ca762588938 /src | |
parent | c2ab38bdd57a16e6c708dcc633d9162331c9d311 (diff) |
random: fix crash on some 64bit platforms
rbx needs to be stashed in a 64bit register on 64bit platforms. With this crash
in particular, it was holding a stack canary which was not properly restored
after the cpuid.
Split out the x86+PIC case so that x86_64 doesn't have to worry about it.
Diffstat (limited to 'src')
-rw-r--r-- | src/random.cpp | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/src/random.cpp b/src/random.cpp index 7916643263..67efc7d945 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -72,10 +72,16 @@ static bool rdrand_supported = false; static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000; static void RDRandInit() { - //! When calling cpuid function #1, ecx register will have this set if RDRAND is available. + uint32_t eax, ecx, edx; +#if defined(__i386__) && ( defined(__PIC__) || defined(__PIE__)) // Avoid clobbering ebx, as that is used for PIC on x86. - uint32_t eax, tmp, ecx, edx; + uint32_t tmp; __asm__ ("mov %%ebx, %1; cpuid; mov %1, %%ebx": "=a"(eax), "=g"(tmp), "=c"(ecx), "=d"(edx) : "a"(1)); +#else + uint32_t ebx; + __asm__ ("cpuid": "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1)); +#endif + //! When calling cpuid function #1, ecx register will have this set if RDRAND is available. if (ecx & CPUID_F1_ECX_RDRAND) { LogPrintf("Using RdRand as entropy source\n"); rdrand_supported = true; |