233#if QT_CONFIG(randomgenerator_disable_fallback)
236 fprintf(stderr,
"QRandomGenerator: falling back to unsafe PRNG is explicitly "
237 "disabled in the configuration. Terminating the application.\n"
238 "Check why /dev/urandom is not available on your system or "
239 "configure Qt with FEATURE_randomgenerator_disable_fallback=OFF "
240 "to enable the fallback.\n");
245 quint32 *end = scratch;
247 auto foldPointer = [](quintptr v) {
248 if (
sizeof(quintptr) ==
sizeof(quint32)) {
256 return quint32(v >> (32 - 24));
262 std::call_once(fallbackFillWarningFlag, [left] {
264 "QRandomGenerator: falling back to unsafe PRNG to initialize %lld element(s).\n"
265 "Configure Qt with FEATURE_randomgenerator_disable_fallback=ON to forbid the "
266 "fallback and terminate the application.\n", qlonglong(left));
270 *end++ = foldPointer(quintptr(&seed));
271 *end++ = foldPointer(quintptr(&scratch));
272 *end++ = foldPointer(quintptr(&errno));
273 *end++ = foldPointer(quintptr(
reinterpret_cast<
void*>(strerror)));
275#ifndef QT_BOOTSTRAPPED
276 quint64 nsecs = QDeadlineTimer::current(Qt::PreciseTimer).deadline();
277 *end++ = quint32(nsecs);
280 if (quint32 v = seed.loadRelaxed())
283#if QT_CONFIG(getauxval)
288 ulong auxvSeed = getauxval(AT_RANDOM);
290 memcpy(end,
reinterpret_cast<
void *>(auxvSeed), 16);
300 ulong base = getauxval(AT_BASE);
302 *end++ = foldPointer(base);
304# ifdef AT_SYSINFO_EHDR
306 ulong sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
308 *end++ = foldPointer(sysinfo_ehdr);
315 std::seed_seq sseq(scratch, end);
316 std::mt19937 generator(sseq);
317 std::generate(ptr, ptr + left, generator);
319 fallback_update_seed(*ptr);
327 quint32 *buffer = begin;
328 qsizetype count = end - begin;
330 if (Q_UNLIKELY(uint(qt_randomdevice_control.loadAcquire()) &
SetRandomData)) {
331 uint value = uint(qt_randomdevice_control.loadAcquire()) &
RandomDataMask;
332 std::fill_n(buffer, count, value);
336 qsizetype filled = 0;
337 if ((uint(qt_randomdevice_control.loadAcquire()) &
SkipSystemRNG) == 0) {
338 qsizetype bytesFilled =
339 fillBuffer(buffer + filled, (count - filled) * qsizetype(
sizeof(*buffer)));
340 filled += bytesFilled / qsizetype(
sizeof(*buffer));
343 fallback_update_seed(*buffer);
345 if (Q_UNLIKELY(filled != count)) {
347 fallback_fill(buffer + filled, count - filled);
1335#if QT_CONFIG(getauxval) && defined(AT_RANDOM)
1336 auto at_random_ptr =
reinterpret_cast<size_t *>(getauxval(AT_RANDOM));
1338 return qFromUnaligned<QRandomGenerator::InitialRandomData>(at_random_ptr);
1343 QRandomGenerator::InitialRandomData v;
1344 for (
int attempts = 16; attempts; --attempts) {
1346 auto fillBuffer = &Generator::fillBuffer;
1347 if (callFillBuffer<Generator>(fillBuffer, &v) !=
sizeof(v))
1353 quint32 data[
sizeof(v) /
sizeof(quint32)];
1354 fallback_fill(data,
std::size(data));
1355 memcpy(v.data, data,
sizeof(v.data));