Kernel.Fs: Device file cleanup and /dev/rng implementation (#3682)

* Add RNG device

* rng device implementation

Tailored around libSceSsl2's usage, and based on fpPS4's implementation.

* Device file function types and log fixups

* Updated creates

Updates device file create functions to be the same as the directory file create functions.

* Fix compile

* Includes cleanup

Generally preferred to have full paths. Also removed some unused imports too.

* Fix buffer size

* Bring back cstdlib imports

Needed for Mac OS.
This commit is contained in:
Stephen Miller
2025-10-01 14:20:58 -05:00
committed by GitHub
parent 6d0b179d24
commit 6fb64a8054
19 changed files with 373 additions and 247 deletions

View File

@@ -769,6 +769,8 @@ set(CORE src/core/aerolib/stubs.cpp
src/core/file_sys/devices/deci_tty6_device.h
src/core/file_sys/devices/random_device.cpp
src/core/file_sys/devices/random_device.h
src/core/file_sys/devices/rng_device.cpp
src/core/file_sys/devices/rng_device.h
src/core/file_sys/devices/urandom_device.cpp
src/core/file_sys/devices/urandom_device.h
src/core/file_sys/devices/srandom_device.cpp

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "base_device.h"
#include "core/file_sys/devices/base_device.h"
namespace Core::Devices {

View File

@@ -3,9 +3,9 @@
#pragma once
#include <core/libraries/kernel/orbis_error.h>
#include "common/types.h"
#include "common/va_ctx.h"
#include "core/libraries/kernel/orbis_error.h"
namespace Libraries::Kernel {
struct OrbisKernelStat;
@@ -20,27 +20,27 @@ public:
virtual ~BaseDevice() = 0;
virtual int ioctl(u64 cmd, Common::VaCtx* args) {
virtual s32 ioctl(u64 cmd, Common::VaCtx* args) {
return ORBIS_KERNEL_ERROR_ENOTTY;
}
virtual s64 write(const void* buf, size_t nbytes) {
virtual s64 write(const void* buf, u64 nbytes) {
return ORBIS_KERNEL_ERROR_EBADF;
}
virtual size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
virtual s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
return ORBIS_KERNEL_ERROR_EBADF;
}
virtual size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
virtual s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
return ORBIS_KERNEL_ERROR_EBADF;
}
virtual s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
virtual s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) {
return ORBIS_KERNEL_ERROR_EBADF;
}
virtual size_t pwritev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
virtual s64 pwritev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) {
return ORBIS_KERNEL_ERROR_EBADF;
}
@@ -48,11 +48,11 @@ public:
return ORBIS_KERNEL_ERROR_EBADF;
}
virtual s64 read(void* buf, size_t nbytes) {
virtual s64 read(void* buf, u64 nbytes) {
return ORBIS_KERNEL_ERROR_EBADF;
}
virtual int fstat(Libraries::Kernel::OrbisKernelStat* sb) {
virtual s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) {
return ORBIS_KERNEL_ERROR_EBADF;
}
@@ -60,15 +60,15 @@ public:
return ORBIS_KERNEL_ERROR_EBADF;
}
virtual int ftruncate(s64 length) {
virtual s32 ftruncate(s64 length) {
return ORBIS_KERNEL_ERROR_EBADF;
}
virtual int getdents(void* buf, u32 nbytes, s64* basep) {
virtual s64 getdents(void* buf, u32 nbytes, s64* basep) {
return ORBIS_KERNEL_ERROR_EBADF;
}
virtual s64 pwrite(const void* buf, size_t nbytes, u64 offset) {
virtual s64 pwrite(const void* buf, u64 nbytes, s64 offset) {
return ORBIS_KERNEL_ERROR_EBADF;
}
};

View File

@@ -2,72 +2,71 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "console_device.h"
#include "core/file_sys/devices/console_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> ConsoleDevice::Create(u32 handle, const char*, int, u16) {
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new ConsoleDevice(handle)));
std::shared_ptr<BaseDevice> ConsoleDevice::Create(u32 handle, const char*, s32, u16) {
return std::static_pointer_cast<BaseDevice>(std::make_shared<ConsoleDevice>(handle));
}
int ConsoleDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 ConsoleDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called, cmd = {:#x}", cmd);
return 0;
}
s64 ConsoleDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 ConsoleDevice::write(const void* buf, u64 nbytes) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
size_t ConsoleDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 ConsoleDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
size_t ConsoleDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 ConsoleDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 ConsoleDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 ConsoleDevice::lseek(s64 offset, s32 whence) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::read(void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 ConsoleDevice::read(void* buf, u64 nbytes) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
int ConsoleDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 ConsoleDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s32 ConsoleDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
int ConsoleDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 ConsoleDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
int ConsoleDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 ConsoleDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 ConsoleDevice::pwrite(const void* buf, u64 nbytes, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}

View File

@@ -3,31 +3,31 @@
#pragma once
#include <memory>
#include "base_device.h"
#include "core/file_sys/devices/base_device.h"
namespace Core::Devices {
class ConsoleDevice final : BaseDevice {
class ConsoleDevice final : public BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, s32, u16);
explicit ConsoleDevice(u32 handle) : handle(handle) {}
~ConsoleDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, u64 nbytes) override;
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) override;
s64 lseek(s64 offset, s32 whence) override;
s64 read(void* buf, u64 nbytes) override;
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
s32 ftruncate(s64 length) override;
s64 getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, u64 nbytes, s64 offset) override;
};
} // namespace Core::Devices

View File

@@ -2,72 +2,71 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "deci_tty6_device.h"
#include "core/file_sys/devices/deci_tty6_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> DeciTty6Device::Create(u32 handle, const char*, int, u16) {
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new DeciTty6Device(handle)));
std::shared_ptr<BaseDevice> DeciTty6Device::Create(u32 handle, const char*, s32, u16) {
return std::static_pointer_cast<BaseDevice>(std::make_shared<DeciTty6Device>(handle));
}
int DeciTty6Device::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 DeciTty6Device::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called, cmd = {:#x}", cmd);
return 0;
}
s64 DeciTty6Device::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 DeciTty6Device::write(const void* buf, u64 nbytes) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
size_t DeciTty6Device::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 DeciTty6Device::writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
size_t DeciTty6Device::readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 DeciTty6Device::readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 DeciTty6Device::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 DeciTty6Device::lseek(s64 offset, s32 whence) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::read(void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 DeciTty6Device::read(void* buf, u64 nbytes) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
int DeciTty6Device::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 DeciTty6Device::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s32 DeciTty6Device::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
int DeciTty6Device::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 DeciTty6Device::ftruncate(s64 length) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
int DeciTty6Device::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 DeciTty6Device::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 DeciTty6Device::pwrite(const void* buf, u64 nbytes, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}

View File

@@ -3,31 +3,31 @@
#pragma once
#include <memory>
#include "base_device.h"
#include "core/file_sys/devices/base_device.h"
namespace Core::Devices {
class DeciTty6Device final : BaseDevice {
class DeciTty6Device final : public BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, s32, u16);
explicit DeciTty6Device(u32 handle) : handle(handle) {}
~DeciTty6Device() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, u64 nbytes) override;
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) override;
s64 lseek(s64 offset, s32 whence) override;
s64 read(void* buf, u64 nbytes) override;
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
s32 ftruncate(s64 length) override;
s64 getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, u64 nbytes, s64 offset) override;
};
} // namespace Core::Devices

View File

@@ -2,8 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "core/file_sys/devices/logger.h"
#include "core/libraries/kernel/file_system.h"
#include "logger.h"
namespace Core::Devices {
@@ -11,13 +11,13 @@ Logger::Logger(std::string prefix, bool is_err) : prefix(std::move(prefix)), is_
Logger::~Logger() = default;
s64 Logger::write(const void* buf, size_t nbytes) {
s64 Logger::write(const void* buf, u64 nbytes) {
log(static_cast<const char*>(buf), nbytes);
return nbytes;
}
size_t Logger::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
size_t total_written = 0;
s64 Logger::writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
u64 total_written = 0;
for (int i = 0; i < iovcnt; i++) {
log(static_cast<const char*>(iov[i].iov_base), iov[i].iov_len);
total_written += iov[i].iov_len;
@@ -25,7 +25,7 @@ size_t Logger::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt
return total_written;
}
s64 Logger::pwrite(const void* buf, size_t nbytes, u64 offset) {
s64 Logger::pwrite(const void* buf, u64 nbytes, s64 offset) {
log(static_cast<const char*>(buf), nbytes);
return nbytes;
}
@@ -35,7 +35,7 @@ s32 Logger::fsync() {
return 0;
}
void Logger::log(const char* buf, size_t nbytes) {
void Logger::log(const char* buf, u64 nbytes) {
std::scoped_lock lock{mtx};
const char* end = buf + nbytes;
for (const char* it = buf; it < end; ++it) {

View File

@@ -3,7 +3,7 @@
#pragma once
#include "base_device.h"
#include "core/file_sys/devices/base_device.h"
#include <mutex>
#include <string>
@@ -23,14 +23,14 @@ public:
~Logger() override;
s64 write(const void* buf, size_t nbytes) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
s64 write(const void* buf, u64 nbytes) override;
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 pwrite(const void* buf, u64 nbytes, s64 offset) override;
s32 fsync() override;
private:
void log(const char* buf, size_t nbytes);
void log(const char* buf, u64 nbytes);
void log_flush();
};

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "base_device.h"
#include "core/file_sys/devices/base_device.h"
namespace Core::Devices {
@@ -14,35 +14,35 @@ public:
~NopDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override {
s32 ioctl(u64 cmd, Common::VaCtx* args) override {
return 0;
}
s64 write(const void* buf, size_t nbytes) override {
s64 write(const void* buf, u64 nbytes) override {
return 0;
}
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override {
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override {
return 0;
}
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override {
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override {
return 0;
}
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override {
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) override {
return 0;
}
s64 lseek(s64 offset, int whence) override {
s64 lseek(s64 offset, s32 whence) override {
return 0;
}
s64 read(void* buf, size_t nbytes) override {
s64 read(void* buf, u64 nbytes) override {
return 0;
}
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override {
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override {
return 0;
}
@@ -50,15 +50,15 @@ public:
return 0;
}
int ftruncate(s64 length) override {
s32 ftruncate(s64 length) override {
return 0;
}
int getdents(void* buf, u32 nbytes, s64* basep) override {
s64 getdents(void* buf, u32 nbytes, s64* basep) override {
return 0;
}
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override {
s64 pwrite(const void* buf, u64 nbytes, s64 offset) override {
return 0;
}
};

View File

@@ -4,75 +4,75 @@
#include <cstdlib>
#include <ctime>
#include "common/logging/log.h"
#include "random_device.h"
#include "core/file_sys/devices/random_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> RandomDevice::Create(u32 handle, const char*, int, u16) {
std::shared_ptr<BaseDevice> RandomDevice::Create(u32 handle, const char*, s32, u16) {
std::srand(std::time(nullptr));
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new RandomDevice(handle)));
return std::static_pointer_cast<BaseDevice>(std::make_shared<RandomDevice>(handle));
}
int RandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 RandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called, cmd = {:#x}", cmd);
return 0;
}
s64 RandomDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 RandomDevice::write(const void* buf, u64 nbytes) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
size_t RandomDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 RandomDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
size_t RandomDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 RandomDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 RandomDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 RandomDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 RandomDevice::lseek(s64 offset, int whence) {
s64 RandomDevice::lseek(s64 offset, s32 whence) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 RandomDevice::read(void* buf, size_t nbytes) {
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < nbytes; i++) {
s64 RandomDevice::read(void* buf, u64 nbytes) {
auto rbuf = static_cast<s8*>(buf);
for (u64 i = 0; i < nbytes; i++) {
rbuf[i] = std::rand() & 0xFF;
}
return nbytes;
}
int RandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 RandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s32 RandomDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
int RandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 RandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
int RandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 RandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 RandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 RandomDevice::pwrite(const void* buf, u64 nbytes, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}

View File

@@ -3,31 +3,31 @@
#pragma once
#include <memory>
#include "base_device.h"
#include "core/file_sys/devices/base_device.h"
namespace Core::Devices {
class RandomDevice final : BaseDevice {
class RandomDevice final : public BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, s32, u16);
explicit RandomDevice(u32 handle) : handle(handle) {}
~RandomDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, u64 nbytes) override;
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) override;
s64 lseek(s64 offset, s32 whence) override;
s64 read(void* buf, u64 nbytes) override;
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
s32 ftruncate(s64 length) override;
s64 getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, u64 nbytes, s64 offset) override;
};
} // namespace Core::Devices

View File

@@ -0,0 +1,87 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cstdlib>
#include <ctime>
#include "common/logging/log.h"
#include "core/file_sys/devices/rng_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> RngDevice::Create(u32 handle, const char*, s32, u16) {
std::srand(std::time(nullptr));
return std::static_pointer_cast<BaseDevice>(std::make_shared<RngDevice>(handle));
}
s32 RngDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_INFO(Kernel_Pthread, "called, cmd = {:#x}", cmd);
// Both commands are for generating a random number
if (cmd == 0x40445301 || cmd == 0x40445302) {
auto& data = *vaArgPtr<GetRandomArgs>(&args->va_list);
data.result = 0;
for (u64 i = 0; i < 64; i++) {
data.buf[i] = std::rand();
}
} else {
// ENOIOCTL
return -3;
}
return 0;
}
s64 RngDevice::write(const void* buf, u64 nbytes) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 RngDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 RngDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 RngDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 RngDevice::lseek(s64 offset, s32 whence) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 RngDevice::read(void* buf, u64 nbytes) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s32 RngDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s32 RngDevice::fsync() {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s32 RngDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 RngDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 RngDevice::pwrite(const void* buf, u64 nbytes, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
} // namespace Core::Devices

View File

@@ -0,0 +1,39 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "core/file_sys/devices/base_device.h"
namespace Core::Devices {
class RngDevice final : public BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, s32, u16);
explicit RngDevice(u32 handle) : handle(handle) {}
~RngDevice() override = default;
s32 ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, u64 nbytes) override;
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) override;
s64 lseek(s64 offset, s32 whence) override;
s64 read(void* buf, u64 nbytes) override;
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
s32 ftruncate(s64 length) override;
s64 getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, u64 nbytes, s64 offset) override;
private:
struct GetRandomArgs {
s32 result;
s8 buf[64];
};
};
} // namespace Core::Devices

View File

@@ -4,76 +4,75 @@
#include <cstdlib>
#include <ctime>
#include "common/logging/log.h"
#include "srandom_device.h"
#include "core/file_sys/devices/srandom_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> SRandomDevice::Create(u32 handle, const char*, int, u16) {
std::shared_ptr<BaseDevice> SRandomDevice::Create(u32 handle, const char*, s32, u16) {
std::srand(std::time(nullptr));
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new SRandomDevice(handle)));
return std::static_pointer_cast<BaseDevice>(std::make_shared<SRandomDevice>(handle));
}
int SRandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 SRandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called, cmd = {:#x}", cmd);
return 0;
}
s64 SRandomDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 SRandomDevice::write(const void* buf, u64 nbytes) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
size_t SRandomDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 SRandomDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
size_t SRandomDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 SRandomDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 SRandomDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 SRandomDevice::lseek(s64 offset, s32 whence) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::read(void* buf, size_t nbytes) {
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < nbytes; i++) {
s64 SRandomDevice::read(void* buf, u64 nbytes) {
auto rbuf = static_cast<s8*>(buf);
for (u64 i = 0; i < nbytes; i++) {
rbuf[i] = std::rand();
}
return nbytes;
}
int SRandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 SRandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s32 SRandomDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return s32();
}
int SRandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
int SRandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 SRandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 SRandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::pwrite(const void* buf, u64 nbytes, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}

View File

@@ -3,31 +3,31 @@
#pragma once
#include <memory>
#include "base_device.h"
#include "core/file_sys/devices/base_device.h"
namespace Core::Devices {
class SRandomDevice final : BaseDevice {
class SRandomDevice final : public BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, s32, u16);
explicit SRandomDevice(u32 handle) : handle(handle) {}
~SRandomDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, u64 nbytes) override;
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) override;
s64 lseek(s64 offset, s32 whence) override;
s64 read(void* buf, u64 nbytes) override;
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
s32 ftruncate(s64 length) override;
s64 getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, u64 nbytes, s64 offset) override;
};
} // namespace Core::Devices

View File

@@ -4,76 +4,75 @@
#include <cstdlib>
#include <ctime>
#include "common/logging/log.h"
#include "urandom_device.h"
#include "core/file_sys/devices/urandom_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> URandomDevice::Create(u32 handle, const char*, int, u16) {
std::shared_ptr<BaseDevice> URandomDevice::Create(u32 handle, const char*, s32, u16) {
std::srand(std::time(nullptr));
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new URandomDevice(handle)));
return std::static_pointer_cast<BaseDevice>(std::make_shared<URandomDevice>(handle));
}
int URandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 URandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called, cmd = {:#x}", cmd);
return 0;
}
s64 URandomDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 URandomDevice::write(const void* buf, u64 nbytes) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
size_t URandomDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 URandomDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
size_t URandomDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 URandomDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 URandomDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 URandomDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 URandomDevice::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 URandomDevice::lseek(s64 offset, s32 whence) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 URandomDevice::read(void* buf, size_t nbytes) {
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < nbytes; i++) {
s64 URandomDevice::read(void* buf, u64 nbytes) {
auto rbuf = static_cast<s8*>(buf);
for (u64 i = 0; i < nbytes; i++) {
rbuf[i] = std::rand() & 0xFF;
}
return nbytes;
}
int URandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 URandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s32 URandomDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
int URandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s32 URandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
int URandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 URandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}
s64 URandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
s64 URandomDevice::pwrite(const void* buf, u64 nbytes, s64 offset) {
LOG_ERROR(Kernel_Fs, "(STUBBED) called");
return 0;
}

View File

@@ -3,31 +3,31 @@
#pragma once
#include <memory>
#include "base_device.h"
#include "core/file_sys/devices/base_device.h"
namespace Core::Devices {
class URandomDevice final : BaseDevice {
class URandomDevice final : public BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, s32, u16);
explicit URandomDevice(u32 handle) : handle(handle) {}
~URandomDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, u64 nbytes) override;
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, s32 iovcnt, s64 offset) override;
s64 lseek(s64 offset, s32 whence) override;
s64 read(void* buf, u64 nbytes) override;
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
s32 ftruncate(s64 length) override;
s64 getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, u64 nbytes, s64 offset) override;
};
} // namespace Core::Devices

View File

@@ -15,6 +15,7 @@
#include "core/file_sys/devices/logger.h"
#include "core/file_sys/devices/nop_device.h"
#include "core/file_sys/devices/random_device.h"
#include "core/file_sys/devices/rng_device.h"
#include "core/file_sys/devices/srandom_device.h"
#include "core/file_sys/devices/urandom_device.h"
#include "core/file_sys/directories/normal_directory.h"
@@ -64,7 +65,8 @@ static std::map<std::string, FactoryDevice> available_device = {
{"/dev/random", &D::RandomDevice::Create },
{"/dev/srandom", &D::SRandomDevice::Create },
{"/dev/console", &D::ConsoleDevice::Create },
{"/dev/deci_tty6",&D::DeciTty6Device::Create }
{"/dev/deci_tty6",&D::DeciTty6Device::Create },
{"/dev/rng", &D::RngDevice::Create },
// clang-format on
};