Index: include/llvm/Support/RandomNumberGenerator.h =================================================================== --- include/llvm/Support/RandomNumberGenerator.h +++ include/llvm/Support/RandomNumberGenerator.h @@ -19,6 +19,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" // Needed for uint64_t on Windows. #include +#include namespace llvm { class StringRef; @@ -53,6 +54,9 @@ friend class Module; }; + +// Get random vector of specified size +std::error_code getRandomBytes(void *Buffer, size_t Size); } #endif Index: lib/Support/RandomNumberGenerator.cpp =================================================================== --- lib/Support/RandomNumberGenerator.cpp +++ lib/Support/RandomNumberGenerator.cpp @@ -17,6 +17,11 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#ifdef LLVM_ON_WIN32 +#include "Windows/WindowsSupport.h" +#else +#include "Unix/Unix.h" +#endif using namespace llvm; @@ -55,3 +60,24 @@ uint_fast64_t RandomNumberGenerator::operator()() { return Generator(); } + +// Get random vector of specified size +std::error_code getRandomBytes(void *Buffer, size_t Size) { +#ifdef LLVM_ON_WIN32 + HCRYPTPROV hProvider; + if (CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { + ScopedCryptContext ScopedHandle(hProvider); + if (CryptGenRandom(hProvider, Size, Buffer)) + return std::error_code(); + } + return std::error_code(GetLastError(), std::system_category()); +#else + int Fd = open("/dev/urandom", O_RDONLY); + if (Fd == -1) + return std::error_code(errno, std::system_category()); + read(Fd, Buffer, Size); + close(Fd); + return std::error_code(); +#endif +} Index: lib/Support/Unix/Unix.h =================================================================== --- lib/Support/Unix/Unix.h +++ lib/Support/Unix/Unix.h @@ -48,6 +48,10 @@ # include #endif +#ifdef HAVE_FCNTL_H +#include +#endif + /// This function builds an error message into \p ErrMsg using the \p prefix /// string and the Unix error number given by \p errnum. If errnum is -1, the /// default then the value of errno is used.