mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-26 00:34:18 +01:00
Address a bunch of issues detected by clang-tidy
This commit is contained in:
parent
9d5138bef1
commit
48acb6d369
@ -5,7 +5,7 @@
|
||||
#include "adpcm_decoder.h"
|
||||
|
||||
namespace skyline::audio {
|
||||
AdpcmDecoder::AdpcmDecoder(const std::vector<std::array<i16, 2>> &coefficients) : coefficients(coefficients) {}
|
||||
AdpcmDecoder::AdpcmDecoder(std::vector<std::array<i16, 2>> coefficients) : coefficients(std::move(coefficients)) {}
|
||||
|
||||
std::vector<i16> AdpcmDecoder::Decode(span<u8> adpcmData) {
|
||||
constexpr size_t BytesPerFrame{0x8};
|
||||
|
@ -26,7 +26,7 @@ namespace skyline::audio {
|
||||
std::vector<std::array<i16, 2>> coefficients; //!< The coefficients for decoding the ADPCM stream
|
||||
|
||||
public:
|
||||
AdpcmDecoder(const std::vector<std::array<i16, 2>> &coefficients);
|
||||
AdpcmDecoder(std::vector<std::array<i16, 2>> coefficients);
|
||||
|
||||
/**
|
||||
* @brief Decodes a buffer of ADPCM data into I16 PCM
|
||||
|
@ -12,7 +12,7 @@ namespace skyline {
|
||||
constexpr u8 ChannelCount{2}; //!< The common amount of channels to use for audio output
|
||||
constexpr u16 MixBufferSize{960}; //!< The size of the mix buffer by default
|
||||
constexpr auto PcmFormat{oboe::AudioFormat::I16}; //!< The common PCM data format to use for audio output
|
||||
};
|
||||
}
|
||||
|
||||
namespace audio {
|
||||
enum class AudioFormat : u8 {
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "track.h"
|
||||
|
||||
namespace skyline::audio {
|
||||
AudioTrack::AudioTrack(u8 channelCount, u32 sampleRate, const std::function<void()> &releaseCallback) : channelCount(channelCount), sampleRate(sampleRate), releaseCallback(releaseCallback) {
|
||||
AudioTrack::AudioTrack(u8 channelCount, u32 sampleRate, std::function<void()> releaseCallback) : channelCount(channelCount), sampleRate(sampleRate), releaseCallback(std::move(releaseCallback)) {
|
||||
if (sampleRate != constant::SampleRate)
|
||||
throw exception("Unsupported audio sample rate: {}", sampleRate);
|
||||
|
||||
|
@ -31,12 +31,12 @@ namespace skyline::audio {
|
||||
* @param sampleRate The sample rate to use for the track
|
||||
* @param releaseCallback A callback to call when a buffer has been played
|
||||
*/
|
||||
AudioTrack(u8 channelCount, u32 sampleRate, const std::function<void()> &releaseCallback);
|
||||
AudioTrack(u8 channelCount, u32 sampleRate, std::function<void()> releaseCallback);
|
||||
|
||||
/**
|
||||
* @brief Starts audio playback using data from appended buffers
|
||||
*/
|
||||
inline void Start() {
|
||||
void Start() {
|
||||
playbackState = AudioOutState::Started;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ namespace skyline {
|
||||
logFile << "\0360\035" << str << '\n';
|
||||
}
|
||||
|
||||
void Logger::Write(LogLevel level, const std::string& str) {
|
||||
void Logger::Write(LogLevel level, const std::string &str) {
|
||||
constexpr std::array<char, 5> levelCharacter{'E', 'W', 'I', 'D', 'V'}; // The LogLevel as written out to a file
|
||||
constexpr std::array<int, 5> levelAlog{ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE}; // This corresponds to LogLevel and provides its equivalent for NDK Logging
|
||||
|
||||
|
@ -73,10 +73,7 @@ namespace skyline {
|
||||
*/
|
||||
Result() = default;
|
||||
|
||||
constexpr Result(u16 module, u16 id) {
|
||||
this->module = module;
|
||||
this->id = id;
|
||||
}
|
||||
constexpr Result(u16 module, u16 id) : module(module), id(id) {}
|
||||
|
||||
constexpr operator u32() const {
|
||||
return raw;
|
||||
@ -121,7 +118,7 @@ namespace skyline {
|
||||
* @param args The arguments based on format_str
|
||||
*/
|
||||
template<typename S, typename... Args>
|
||||
inline exception(const S &formatStr, Args &&... args) : runtime_error(fmt::format(formatStr, util::FmtCast(args)...)) {}
|
||||
exception(const S &formatStr, Args &&... args) : runtime_error(fmt::format(formatStr, util::FmtCast(args)...)) {}
|
||||
};
|
||||
|
||||
namespace util {
|
||||
@ -434,31 +431,31 @@ namespace skyline {
|
||||
void Write(LogLevel level, const std::string &str);
|
||||
|
||||
template<typename S, typename... Args>
|
||||
inline void Error(const S &formatStr, Args &&... args) {
|
||||
void Error(const S &formatStr, Args &&... args) {
|
||||
if (LogLevel::Error <= configLevel)
|
||||
Write(LogLevel::Error, fmt::format(formatStr, util::FmtCast(args)...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
inline void Warn(const S &formatStr, Args &&... args) {
|
||||
void Warn(const S &formatStr, Args &&... args) {
|
||||
if (LogLevel::Warn <= configLevel)
|
||||
Write(LogLevel::Warn, fmt::format(formatStr, util::FmtCast(args)...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
inline void Info(const S &formatStr, Args &&... args) {
|
||||
void Info(const S &formatStr, Args &&... args) {
|
||||
if (LogLevel::Info <= configLevel)
|
||||
Write(LogLevel::Info, fmt::format(formatStr, util::FmtCast(args)...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
inline void Debug(const S &formatStr, Args &&... args) {
|
||||
void Debug(const S &formatStr, Args &&... args) {
|
||||
if (LogLevel::Debug <= configLevel)
|
||||
Write(LogLevel::Debug, fmt::format(formatStr, util::FmtCast(args)...));
|
||||
}
|
||||
|
||||
template<typename S, typename... Args>
|
||||
inline void Verbose(const S &formatStr, Args &&... args) {
|
||||
void Verbose(const S &formatStr, Args &&... args) {
|
||||
if (LogLevel::Verbose <= configLevel)
|
||||
Write(LogLevel::Verbose, fmt::format(formatStr, util::FmtCast(args)...));
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace skyline {
|
||||
* @param copyOffset The offset into the buffer after which to use memcpy rather than copyFunction, -1 will use it for the entire buffer
|
||||
* @return The amount of data written into the input buffer in units of Type
|
||||
*/
|
||||
inline size_t Read(span <Type> buffer, void copyFunction(Type *, Type *) = {}, ssize_t copyOffset = -1) {
|
||||
size_t Read(span <Type> buffer, void copyFunction(Type *, Type *) = {}, ssize_t copyOffset = -1) {
|
||||
std::lock_guard guard(mtx);
|
||||
|
||||
if (empty)
|
||||
@ -91,7 +91,7 @@ namespace skyline {
|
||||
/**
|
||||
* @brief Appends data from the specified buffer into this buffer
|
||||
*/
|
||||
inline void Append(span <Type> buffer) {
|
||||
void Append(span <Type> buffer) {
|
||||
std::lock_guard guard(mtx);
|
||||
|
||||
Type *pointer{buffer.data()};
|
||||
|
@ -24,19 +24,19 @@ namespace skyline {
|
||||
/**
|
||||
* @note The internal allocation is an item larger as we require a sentinel value
|
||||
*/
|
||||
inline CircularQueue(size_t size) : vector((size + 1) * sizeof(Type)) {}
|
||||
CircularQueue(size_t size) : vector((size + 1) * sizeof(Type)) {}
|
||||
|
||||
inline CircularQueue(const CircularQueue &) = delete;
|
||||
CircularQueue(const CircularQueue &) = delete;
|
||||
|
||||
inline CircularQueue &operator=(const CircularQueue &) = delete;
|
||||
CircularQueue &operator=(const CircularQueue &) = delete;
|
||||
|
||||
inline CircularQueue(CircularQueue &&other) : vector(std::move(other.vector)), consumptionMutex(std::move(other.consumptionMutex)), consumeCondition(std::move(other.consumeCondition)), productionMutex(std::move(other.productionMutex)), produceCondition(std::move(other.produceCondition)) {
|
||||
this->start = other.start;
|
||||
this->end = other.end;
|
||||
CircularQueue(CircularQueue &&other) : vector(std::move(other.vector)), consumptionMutex(std::move(other.consumptionMutex)), consumeCondition(std::move(other.consumeCondition)), productionMutex(std::move(other.productionMutex)), produceCondition(std::move(other.produceCondition)) {
|
||||
start = other.start;
|
||||
end = other.end;
|
||||
other.start = other.end = nullptr;
|
||||
}
|
||||
|
||||
inline ~CircularQueue() {
|
||||
~CircularQueue() {
|
||||
while (start != end) {
|
||||
auto next{start + 1};
|
||||
next = (next == reinterpret_cast<Type *>(vector.end().base())) ? reinterpret_cast<Type *>(vector.begin().base()) : next;
|
||||
@ -50,7 +50,7 @@ namespace skyline {
|
||||
* @param function A function that is called for each item (with the only parameter as a reference to that item)
|
||||
*/
|
||||
template<typename F>
|
||||
[[noreturn]] inline void Process(F function) {
|
||||
[[noreturn]] void Process(F function) {
|
||||
while (true) {
|
||||
if (start == end) {
|
||||
std::unique_lock lock(productionMutex);
|
||||
@ -68,7 +68,7 @@ namespace skyline {
|
||||
}
|
||||
}
|
||||
|
||||
inline void Push(const Type &item) {
|
||||
void Push(const Type &item) {
|
||||
std::unique_lock lock(productionMutex);
|
||||
end = (end == reinterpret_cast<Type *>(vector.end().base()) - 1) ? reinterpret_cast<Type *>(vector.begin().base()) : end;
|
||||
if (start == end + 1) {
|
||||
@ -79,7 +79,7 @@ namespace skyline {
|
||||
produceCondition.notify_one();
|
||||
}
|
||||
|
||||
inline void Append(span <Type> buffer) {
|
||||
void Append(span <Type> buffer) {
|
||||
std::unique_lock lock(productionMutex);
|
||||
for (const auto &item : buffer) {
|
||||
auto next{end + 1};
|
||||
@ -99,7 +99,7 @@ namespace skyline {
|
||||
* @param tranformation A function that takes in an item of TransformedType as input and returns an item of Type
|
||||
*/
|
||||
template<typename TransformedType, typename Transformation>
|
||||
inline void AppendTranform(span <TransformedType> buffer, Transformation transformation) {
|
||||
void AppendTranform(span <TransformedType> buffer, Transformation transformation) {
|
||||
std::unique_lock lock(productionMutex);
|
||||
for (const auto &item : buffer) {
|
||||
auto next{end + 1};
|
||||
|
@ -49,7 +49,7 @@ namespace skyline::signal {
|
||||
void *fault{};
|
||||
std::vector<void *> frames; //!< A vector of all stack frame entries prior to the signal occuring
|
||||
|
||||
inline std::string what() const {
|
||||
std::string what() const {
|
||||
if (!fault)
|
||||
return fmt::format("Signal: {} (PC: 0x{:X})", strsignal(signal), reinterpret_cast<uintptr_t>(pc));
|
||||
else
|
||||
|
@ -19,7 +19,7 @@ namespace skyline::crypto {
|
||||
/**
|
||||
* @brief Calculates IV for XTS, basically just big to little endian conversion
|
||||
*/
|
||||
inline static std::array<u8, 0x10> GetTweak(size_t sector) {
|
||||
static std::array<u8, 0x10> GetTweak(size_t sector) {
|
||||
std::array<u8, 0x10> tweak{};
|
||||
size_t le{__builtin_bswap64(sector)};
|
||||
std::memcpy(tweak.data() + 8, &le, 8);
|
||||
@ -45,7 +45,7 @@ namespace skyline::crypto {
|
||||
/**
|
||||
* @brief Decrypts the supplied data in-place
|
||||
*/
|
||||
inline void Decrypt(span<u8> data) {
|
||||
void Decrypt(span<u8> data) {
|
||||
Decrypt(data.data(), data.data(), data.size());
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ namespace skyline::crypto {
|
||||
/**
|
||||
* @brief Decrypts data with XTS and writes back to it
|
||||
*/
|
||||
inline void XtsDecrypt(span<u8> data, size_t sector, size_t sectorSize) {
|
||||
void XtsDecrypt(span<u8> data, size_t sector, size_t sectorSize) {
|
||||
XtsDecrypt(data.data(), data.data(), data.size(), sector, sectorSize);
|
||||
}
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ namespace skyline::crypto {
|
||||
void KeyStore::PopulateTitleKeys(std::string_view keyName, std::string_view value) {
|
||||
Key128 key{util::HexStringToArray<16>(keyName)};
|
||||
Key128 valueArray{util::HexStringToArray<16>(value)};
|
||||
titleKeys.insert({std::move(key), std::move(valueArray)});
|
||||
titleKeys.emplace(key, valueArray);
|
||||
}
|
||||
|
||||
void KeyStore::PopulateKeys(std::string_view keyName, std::string_view value) {
|
||||
|
@ -47,7 +47,7 @@ namespace skyline::crypto {
|
||||
void PopulateKeys(std::string_view keyName, std::string_view value);
|
||||
|
||||
public:
|
||||
inline std::optional<Key128> GetTitleKey(const Key128 &title) {
|
||||
std::optional<Key128> GetTitleKey(const Key128 &title) {
|
||||
auto it{titleKeys.find(title)};
|
||||
if (it == titleKeys.end())
|
||||
return std::nullopt;
|
||||
|
@ -27,6 +27,6 @@ namespace skyline::gpu {
|
||||
std::array<Syncpoint, constant::MaxHwSyncpointCount> syncpoints{};
|
||||
gpfifo::GPFIFO gpfifo;
|
||||
|
||||
inline GPU(const DeviceState &state) : state(state), presentation(state), memoryManager(state), gpfifo(state), fermi2D(std::make_shared<engine::Engine>(state)), keplerMemory(std::make_shared<engine::Engine>(state)), maxwell3D(std::make_shared<engine::Maxwell3D>(state)), maxwellCompute(std::make_shared<engine::Engine>(state)), maxwellDma(std::make_shared<engine::Engine>(state)) {}
|
||||
GPU(const DeviceState &state) : state(state), presentation(state), memoryManager(state), gpfifo(state), fermi2D(std::make_shared<engine::Engine>(state)), keplerMemory(std::make_shared<engine::Engine>(state)), maxwell3D(std::make_shared<engine::Maxwell3D>(state)), maxwellCompute(std::make_shared<engine::Engine>(state)), maxwellDma(std::make_shared<engine::Engine>(state)) {}
|
||||
};
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ namespace skyline {
|
||||
public:
|
||||
GPFIFO(const DeviceState &state) : Engine(state) {}
|
||||
|
||||
void CallMethod(MethodParams params) {
|
||||
void CallMethod(MethodParams params) override {
|
||||
state.logger->Debug("Called method in GPFIFO: 0x{:X} args: 0x{:X}", params.method, params.argument);
|
||||
|
||||
registers.raw[params.method] = params.argument;
|
||||
|
@ -569,7 +569,7 @@ namespace skyline {
|
||||
*/
|
||||
void ResetRegs();
|
||||
|
||||
void CallMethod(MethodParams params);
|
||||
void CallMethod(MethodParams params) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +91,8 @@ namespace skyline::gpu {
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw exception("Unknown MME opcode encountered: 0x{:X}", static_cast<u8>(opcode->operation));
|
||||
}
|
||||
|
||||
if (opcode->exit && (delayedOpcode == nullptr)) {
|
||||
|
@ -124,7 +124,7 @@ namespace skyline::gpu::vmm {
|
||||
|
||||
u64 MemoryManager::MapFixed(u64 virtAddr, u8 *cpuPtr, u64 size) {
|
||||
if (!util::IsAligned(virtAddr, constant::GpuPageSize))
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
size = util::AlignUp(size, constant::GpuPageSize);
|
||||
|
||||
|
@ -29,7 +29,7 @@ namespace skyline {
|
||||
* @return If the given chunk can be contained wholly within this chunk
|
||||
*/
|
||||
inline bool CanContain(const ChunkDescriptor &chunk) {
|
||||
return (chunk.virtAddr >= this->virtAddr) && ((this->size + this->virtAddr) >= (chunk.size + chunk.virtAddr));
|
||||
return (chunk.virtAddr >= virtAddr) && ((size + virtAddr) >= (chunk.size + chunk.virtAddr));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,7 +11,7 @@ namespace skyline::gpu {
|
||||
}
|
||||
|
||||
std::lock_guard guard(waiterLock);
|
||||
waiterMap.insert({nextWaiterId, Waiter{threshold, callback}});
|
||||
waiterMap.emplace(nextWaiterId, Waiter{threshold, callback});
|
||||
|
||||
return nextWaiterId++;
|
||||
}
|
||||
@ -42,7 +42,7 @@ namespace skyline::gpu {
|
||||
std::condition_variable cv;
|
||||
bool flag{};
|
||||
|
||||
if (timeout == timeout.max())
|
||||
if (timeout == std::chrono::steady_clock::duration::max())
|
||||
timeout = std::chrono::seconds(1);
|
||||
|
||||
if (!RegisterWaiter(threshold, [&cv, &mtx, &flag] {
|
||||
@ -57,5 +57,5 @@ namespace skyline::gpu {
|
||||
std::unique_lock lock(mtx);
|
||||
return cv.wait_for(lock, timeout, [&flag] { return flag; });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -9,15 +9,15 @@
|
||||
namespace skyline::gpu {
|
||||
GuestTexture::GuestTexture(const DeviceState &state, u8 *pointer, texture::Dimensions dimensions, texture::Format format, texture::TileMode tiling, texture::TileConfig layout) : state(state), pointer(pointer), dimensions(dimensions), format(format), tileMode(tiling), tileConfig(layout) {}
|
||||
|
||||
std::shared_ptr<Texture> GuestTexture::InitializeTexture(std::optional<texture::Format> format, std::optional<texture::Dimensions> dimensions, texture::Swizzle swizzle) {
|
||||
std::shared_ptr<Texture> GuestTexture::InitializeTexture(std::optional<texture::Format> pFormat, std::optional<texture::Dimensions> pDimensions, texture::Swizzle swizzle) {
|
||||
if (!host.expired())
|
||||
throw exception("Trying to create multiple Texture objects from a single GuestTexture");
|
||||
auto sharedHost{std::make_shared<Texture>(state, shared_from_this(), dimensions ? *dimensions : this->dimensions, format ? *format : this->format, swizzle)};
|
||||
auto sharedHost{std::make_shared<Texture>(state, shared_from_this(), pDimensions ? *pDimensions : dimensions, pFormat ? *pFormat : format, swizzle)};
|
||||
host = sharedHost;
|
||||
return sharedHost;
|
||||
}
|
||||
|
||||
Texture::Texture(const DeviceState &state, std::shared_ptr<GuestTexture> guest, texture::Dimensions dimensions, texture::Format format, texture::Swizzle swizzle) : state(state), guest(guest), dimensions(dimensions), format(format), swizzle(swizzle) {
|
||||
Texture::Texture(const DeviceState &state, std::shared_ptr<GuestTexture> guest, texture::Dimensions dimensions, texture::Format format, texture::Swizzle swizzle) : state(state), guest(std::move(guest)), dimensions(dimensions), format(format), swizzle(swizzle) {
|
||||
SynchronizeHost();
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ namespace skyline::gpu {
|
||||
auto pointer{guest->pointer};
|
||||
auto size{format.GetSize(dimensions)};
|
||||
backing.resize(size);
|
||||
auto output{reinterpret_cast<u8 *>(backing.data())};
|
||||
auto output{backing.data()};
|
||||
|
||||
if (guest->tileMode == texture::TileMode::Block) {
|
||||
// Reference on Block-linear tiling: https://gist.github.com/PixelyIon/d9c35050af0ef5690566ca9f0965bc32
|
||||
|
@ -24,6 +24,6 @@ namespace skyline::input {
|
||||
NpadManager npad;
|
||||
TouchManager touch;
|
||||
|
||||
inline Input(const DeviceState &state) : state(state), kHid(std::make_shared<kernel::type::KSharedMemory>(state, sizeof(HidSharedMemory))), hid(reinterpret_cast<HidSharedMemory *>(kHid->kernel.ptr)), npad(state, hid), touch(state, hid) {}
|
||||
Input(const DeviceState &state) : state(state), kHid(std::make_shared<kernel::type::KSharedMemory>(state, sizeof(HidSharedMemory))), hid(reinterpret_cast<HidSharedMemory *>(kHid->kernel.ptr)), npad(state, hid), touch(state, hid) {}
|
||||
};
|
||||
}
|
||||
|
@ -89,8 +89,9 @@ namespace skyline::input {
|
||||
return NpadControllerType::JoyconLeft;
|
||||
case 7:
|
||||
return NpadControllerType::JoyconRight;
|
||||
default:
|
||||
return NpadControllerType::None;
|
||||
}
|
||||
return NpadControllerType::None;
|
||||
}
|
||||
};
|
||||
|
||||
@ -146,11 +147,11 @@ namespace skyline::input {
|
||||
|
||||
NpadDevice(NpadManager &manager, NpadSection §ion, NpadId id);
|
||||
|
||||
inline void SetAssignment(NpadJoyAssignment assignment) {
|
||||
void SetAssignment(NpadJoyAssignment assignment) {
|
||||
section.header.assignment = assignment;
|
||||
}
|
||||
|
||||
inline NpadJoyAssignment GetAssignment() {
|
||||
NpadJoyAssignment GetAssignment() {
|
||||
return section.header.assignment;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ namespace skyline {
|
||||
* @return The contents of the field as objectType
|
||||
*/
|
||||
template<typename objectType>
|
||||
inline objectType GetField(const char *key) {
|
||||
objectType GetField(const char *key) {
|
||||
JNIEnv *env{GetEnv()};
|
||||
if constexpr(std::is_same<objectType, jboolean>())
|
||||
return env->GetBooleanField(instance, env->GetFieldID(instanceClass, key, "Z"));
|
||||
@ -53,6 +53,8 @@ namespace skyline {
|
||||
return env->GetFloatField(instance, env->GetFieldID(instanceClass, key, "F"));
|
||||
else if constexpr(std::is_same<objectType, jdouble>())
|
||||
return env->GetDoubleField(instance, env->GetFieldID(instanceClass, key, "D"));
|
||||
else
|
||||
throw exception("GetField: Unhandled object type");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,19 +129,11 @@ namespace skyline {
|
||||
u16 size : 16; //!< The 16 bit size of the buffer
|
||||
u32 address0_31 : 32; //!< The first 32-bits of the address
|
||||
|
||||
BufferDescriptorX(u64 address, u16 counter, u16 size) : size(size) {
|
||||
address0_31 = static_cast<u32>(address & 0x7FFFFFFF80000000);
|
||||
address32_35 = static_cast<u16>(address & 0x78000000);
|
||||
address36_38 = static_cast<u16>(address & 0x7000000);
|
||||
counter0_5 = static_cast<u16>(address & 0x7E00);
|
||||
counter9_11 = static_cast<u16>(address & 0x38);
|
||||
}
|
||||
|
||||
inline u8 *Pointer() {
|
||||
u8 *Pointer() {
|
||||
return reinterpret_cast<u8 *>(static_cast<u64>(address0_31) | static_cast<u64>(address32_35) << 32 | static_cast<u64>(address36_38) << 36);
|
||||
}
|
||||
|
||||
inline u16 Counter() {
|
||||
u16 Counter() {
|
||||
return static_cast<u16>(counter0_5) | static_cast<u16>(counter9_11) << 9;
|
||||
}
|
||||
};
|
||||
@ -159,19 +151,11 @@ namespace skyline {
|
||||
u8 size32_35 : 4; //!< Bit 32-35 of the size
|
||||
u8 address32_35 : 4; //!< Bit 32-35 of the address
|
||||
|
||||
BufferDescriptorABW(u64 address, u64 size) {
|
||||
address0_31 = static_cast<u32>(address & 0x7FFFFFFF80000000);
|
||||
address32_35 = static_cast<u8>(address & 0x78000000);
|
||||
address36_38 = static_cast<u8>(address & 0x7000000);
|
||||
size0_31 = static_cast<u32>(size & 0x7FFFFFFF80000000);
|
||||
size32_35 = static_cast<u8>(size & 0x78000000);
|
||||
}
|
||||
|
||||
inline u8 *Pointer() {
|
||||
u8 *Pointer() {
|
||||
return reinterpret_cast<u8 *>(static_cast<u64>(address0_31) | static_cast<u64>(address32_35) << 32 | static_cast<u64>(address36_38) << 36);
|
||||
}
|
||||
|
||||
inline u64 Size() {
|
||||
u64 Size() {
|
||||
return static_cast<u64>(size0_31) | static_cast<u64>(size32_35) << 32;
|
||||
}
|
||||
};
|
||||
@ -184,11 +168,9 @@ namespace skyline {
|
||||
u64 address : 48; //!< The 48-bit address of the buffer
|
||||
u32 size : 16; //!< The 16-bit size of the buffer
|
||||
|
||||
inline u8 *Pointer() {
|
||||
u8 *Pointer() {
|
||||
return reinterpret_cast<u8 *>(address);
|
||||
}
|
||||
|
||||
BufferDescriptorC(u64 address, u16 size) : address(address), size(size) {}
|
||||
};
|
||||
static_assert(sizeof(BufferDescriptorC) == 8);
|
||||
|
||||
@ -228,7 +210,7 @@ namespace skyline {
|
||||
* @brief Returns a reference to an item from the top of the payload
|
||||
*/
|
||||
template<typename ValueType>
|
||||
inline ValueType &Pop() {
|
||||
ValueType &Pop() {
|
||||
ValueType &value{*reinterpret_cast<ValueType *>(payloadOffset)};
|
||||
payloadOffset += sizeof(ValueType);
|
||||
return value;
|
||||
@ -238,7 +220,7 @@ namespace skyline {
|
||||
* @brief Returns a std::string_view from the payload
|
||||
* @param size The length of the string (0 means the string is null terminated)
|
||||
*/
|
||||
inline std::string_view PopString(size_t size = 0) {
|
||||
std::string_view PopString(size_t size = 0) {
|
||||
auto view{size ? std::string_view(reinterpret_cast<const char *>(payloadOffset), size) : std::string_view(reinterpret_cast<const char *>(payloadOffset))};
|
||||
payloadOffset += view.length();
|
||||
return view;
|
||||
@ -248,7 +230,7 @@ namespace skyline {
|
||||
* @brief Skips an object to pop off the top
|
||||
*/
|
||||
template<typename ValueType>
|
||||
inline void Skip() {
|
||||
void Skip() {
|
||||
payloadOffset += sizeof(ValueType);
|
||||
}
|
||||
};
|
||||
@ -276,7 +258,7 @@ namespace skyline {
|
||||
* @param value A reference to the object to be written
|
||||
*/
|
||||
template<typename ValueType>
|
||||
inline void Push(const ValueType &value) {
|
||||
void Push(const ValueType &value) {
|
||||
auto size{payload.size()};
|
||||
payload.resize(size + sizeof(ValueType));
|
||||
std::memcpy(payload.data() + size, reinterpret_cast<const u8 *>(&value), sizeof(ValueType));
|
||||
@ -286,7 +268,7 @@ namespace skyline {
|
||||
* @brief Writes a string to the payload
|
||||
* @param string The string to write to the payload
|
||||
*/
|
||||
inline void Push(std::string_view string) {
|
||||
void Push(std::string_view string) {
|
||||
auto size{payload.size()};
|
||||
payload.resize(size + string.size());
|
||||
std::memcpy(payload.data() + size, string.data(), string.size());
|
||||
|
@ -61,7 +61,9 @@ namespace skyline::kernel {
|
||||
if (!base.address)
|
||||
throw exception("Cannot find a suitable carveout for the guest address space");
|
||||
|
||||
mmap(reinterpret_cast<void *>(base.address), base.size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
auto result{mmap(reinterpret_cast<void *>(base.address), base.size, PROT_NONE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)};
|
||||
if (result == MAP_FAILED) [[unlikely]]
|
||||
throw exception("Failed to mmap guest address space: {}", strerror(errno));
|
||||
|
||||
chunks = {
|
||||
ChunkDescriptor{
|
||||
|
@ -25,7 +25,7 @@ namespace skyline {
|
||||
*/
|
||||
constexpr Permission(bool read, bool write, bool execute) : r(read), w(write), x(execute) {}
|
||||
|
||||
inline bool operator==(const Permission &rhs) const { return (this->r == rhs.r && this->w == rhs.w && this->x == rhs.x); }
|
||||
inline bool operator==(const Permission &rhs) const { return r == rhs.r && w == rhs.w && x == rhs.x; }
|
||||
|
||||
inline bool operator!=(const Permission &rhs) const { return !operator==(rhs); }
|
||||
|
||||
@ -176,7 +176,7 @@ namespace skyline {
|
||||
constexpr MemoryState KernelStack{0x00002013};
|
||||
constexpr MemoryState CodeReadOnly{0x00402214};
|
||||
constexpr MemoryState CodeWritable{0x00402015};
|
||||
};
|
||||
}
|
||||
|
||||
struct Region {
|
||||
u64 address;
|
||||
|
@ -62,7 +62,7 @@ namespace skyline {
|
||||
* @note 'KThread::coreMigrationMutex' **must** be locked by the calling thread prior to calling this
|
||||
* @note This is used to handle non-cooperative core affinity mask changes where the resident core is not in its new affinity mask
|
||||
*/
|
||||
void MigrateToCore(const std::shared_ptr<type::KThread> &thread, CoreContext *¤tCore, CoreContext* targetCore, std::unique_lock<std::mutex> &lock);
|
||||
void MigrateToCore(const std::shared_ptr<type::KThread> &thread, CoreContext *¤tCore, CoreContext *targetCore, std::unique_lock<std::mutex> &lock);
|
||||
|
||||
public:
|
||||
static constexpr std::chrono::milliseconds PreemptiveTimeslice{10}; //!< The duration of time a preemptive thread can run before yielding
|
||||
@ -149,11 +149,11 @@ namespace skyline {
|
||||
const DeviceState &state;
|
||||
|
||||
public:
|
||||
inline SchedulerScopedLock(const DeviceState &state) : state(state) {
|
||||
SchedulerScopedLock(const DeviceState &state) : state(state) {
|
||||
state.scheduler->RemoveThread();
|
||||
}
|
||||
|
||||
inline ~SchedulerScopedLock() {
|
||||
~SchedulerScopedLock() {
|
||||
state.scheduler->InsertThread(state.thread);
|
||||
state.scheduler->WaitSchedule();
|
||||
}
|
||||
|
@ -87,4 +87,4 @@ namespace skyline::kernel::type {
|
||||
.state = memory::states::Unmapped,
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -29,16 +29,10 @@ namespace skyline::kernel::type {
|
||||
*/
|
||||
void Remap(u8 *ptr, size_t size);
|
||||
|
||||
inline span<u8> Get() override {
|
||||
span<u8> Get() override {
|
||||
return span(ptr, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the permissions of a block of mapped memory
|
||||
* @param address The starting address to change the permissions at
|
||||
* @param size The size of the partition to change the permissions of
|
||||
* @param permission The new permissions to be set for the memory
|
||||
*/
|
||||
void UpdatePermission(u8 *ptr, size_t size, memory::Permission permission) override;
|
||||
|
||||
/**
|
||||
|
@ -4,10 +4,11 @@
|
||||
#include <nce.h>
|
||||
#include <os.h>
|
||||
#include <kernel/results.h>
|
||||
|
||||
#include "KProcess.h"
|
||||
|
||||
namespace skyline::kernel::type {
|
||||
KProcess::TlsPage::TlsPage(const std::shared_ptr<KPrivateMemory> &memory) : memory(memory) {}
|
||||
KProcess::TlsPage::TlsPage(std::shared_ptr<KPrivateMemory> memory) : memory(std::move(memory)) {}
|
||||
|
||||
u8 *KProcess::TlsPage::ReserveSlot() {
|
||||
if (index == constant::TlsSlots)
|
||||
|
@ -43,7 +43,7 @@ namespace skyline {
|
||||
u8 index{}; //!< The slots are assigned sequentially, this holds the index of the last TLS slot reserved
|
||||
std::shared_ptr<KPrivateMemory> memory; //!< A single page sized memory allocation for this TLS page
|
||||
|
||||
TlsPage(const std::shared_ptr<KPrivateMemory> &memory);
|
||||
TlsPage(std::shared_ptr<KPrivateMemory> memory);
|
||||
|
||||
/**
|
||||
* @return A non-null pointer to a TLS page slot on success, a nullptr will be returned if this page is full
|
||||
@ -197,7 +197,7 @@ namespace skyline {
|
||||
/**
|
||||
* @brief Closes a handle in the handle table
|
||||
*/
|
||||
inline void CloseHandle(KHandle handle) {
|
||||
void CloseHandle(KHandle handle) {
|
||||
handles.at(handle - constant::BaseHandleIndex) = nullptr;
|
||||
}
|
||||
|
||||
|
@ -75,4 +75,4 @@ namespace skyline::kernel::type {
|
||||
|
||||
close(fd);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ namespace skyline::kernel::type {
|
||||
*/
|
||||
u8 *Map(u8 *ptr, u64 size, memory::Permission permission);
|
||||
|
||||
inline span<u8> Get() override {
|
||||
span<u8> Get() override {
|
||||
return span(guest.ptr, guest.size);
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ namespace skyline::kernel::type {
|
||||
if (ownerPriority != currentPriority) {
|
||||
std::lock_guard waiterLock(waitingOn->waiterMutex);
|
||||
auto nextThread{waitingOn->waitThread};
|
||||
if (nextThread){
|
||||
if (nextThread) {
|
||||
// We need to update the location of the owner thread in the waiter queue of the thread it's waiting on
|
||||
std::lock_guard nextWaiterLock(nextThread->waiterMutex);
|
||||
auto &piWaiters{nextThread->waiters};
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "loader.h"
|
||||
|
||||
namespace skyline::loader {
|
||||
Loader::ExecutableLoadInfo Loader::LoadExecutable(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state, Executable &executable, size_t offset, const std::string &name) {
|
||||
Loader::ExecutableLoadInfo Loader::LoadExecutable(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state, Executable &executable, size_t offset, const std::string &name) {
|
||||
u8 *base{reinterpret_cast<u8 *>(process->memory.base.address + offset)};
|
||||
|
||||
u64 textSize{executable.text.contents.size()};
|
||||
@ -109,7 +109,7 @@ namespace skyline::loader {
|
||||
return trace;
|
||||
}
|
||||
|
||||
std::string Loader::GetStackTrace(const std::vector<void *> frames) {
|
||||
std::string Loader::GetStackTrace(const std::vector<void *> &frames) {
|
||||
std::string trace;
|
||||
for (const auto &frame : frames)
|
||||
trace += GetFunctionStackTrace(this, frame);
|
||||
|
@ -80,7 +80,7 @@ namespace skyline::loader {
|
||||
* @param name An optional name for the executable, used for symbol resolution
|
||||
* @return An ExecutableLoadInfo struct containing the load base and size
|
||||
*/
|
||||
ExecutableLoadInfo LoadExecutable(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state, Executable &executable, size_t offset = 0, const std::string &name = {});
|
||||
ExecutableLoadInfo LoadExecutable(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state, Executable &executable, size_t offset = 0, const std::string &name = {});
|
||||
|
||||
std::optional<vfs::NACP> nacp;
|
||||
std::shared_ptr<vfs::Backing> romFs;
|
||||
@ -94,7 +94,7 @@ namespace skyline::loader {
|
||||
/**
|
||||
* @return Entry point to the start of the main executable in the ROM
|
||||
*/
|
||||
virtual void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) = 0;
|
||||
virtual void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) = 0;
|
||||
|
||||
/**
|
||||
* @note The lifetime of the data contained within is tied to the lifetime of the Loader class it was obtained from (as this points to symbols from the executables loaded into memory directly)
|
||||
@ -119,6 +119,6 @@ namespace skyline::loader {
|
||||
/**
|
||||
* @return A string with the stack trace based on the stack frames in the supplied vector
|
||||
*/
|
||||
std::string GetStackTrace(const std::vector<void *> frames);
|
||||
std::string GetStackTrace(const std::vector<void *> &frames);
|
||||
};
|
||||
}
|
||||
|
@ -7,12 +7,12 @@
|
||||
#include "nca.h"
|
||||
|
||||
namespace skyline::loader {
|
||||
NcaLoader::NcaLoader(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore) : nca(backing, keyStore) {
|
||||
NcaLoader::NcaLoader(std::shared_ptr<vfs::Backing> backing, std::shared_ptr<crypto::KeyStore> keyStore) : nca(std::move(backing), std::move(keyStore)) {
|
||||
if (nca.exeFs == nullptr)
|
||||
throw exception("Only NCAs with an ExeFS can be loaded directly");
|
||||
}
|
||||
|
||||
void *NcaLoader::LoadExeFs(Loader *loader, const std::shared_ptr<vfs::FileSystem> &exeFs, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
void *NcaLoader::LoadExeFs(Loader *loader, const std::shared_ptr<vfs::FileSystem> &exeFs, const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) {
|
||||
if (exeFs == nullptr)
|
||||
throw exception("Cannot load a null ExeFS");
|
||||
|
||||
@ -45,7 +45,7 @@ namespace skyline::loader {
|
||||
return entry;
|
||||
}
|
||||
|
||||
void *NcaLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
void *NcaLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) {
|
||||
process->npdm = vfs::NPDM(nca.exeFs->OpenFile("main.npdm"), state);
|
||||
return LoadExeFs(this, nca.exeFs, process, state);
|
||||
}
|
||||
|
@ -16,14 +16,14 @@ namespace skyline::loader {
|
||||
vfs::NCA nca; //!< The backing NCA of the loader
|
||||
|
||||
public:
|
||||
NcaLoader(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore);
|
||||
NcaLoader(std::shared_ptr<vfs::Backing> backing, std::shared_ptr<crypto::KeyStore> keyStore);
|
||||
|
||||
/**
|
||||
* @brief Loads an ExeFS into memory and processes it accordingly for execution
|
||||
* @param exefs A filesystem object containing the ExeFS filesystem to load into memory
|
||||
*/
|
||||
static void *LoadExeFs(Loader *loader, const std::shared_ptr<vfs::FileSystem> &exefs, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
static void *LoadExeFs(Loader *loader, const std::shared_ptr<vfs::FileSystem> &exefs, const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state);
|
||||
|
||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) override;
|
||||
};
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "nro.h"
|
||||
|
||||
namespace skyline::loader {
|
||||
NroLoader::NroLoader(const std::shared_ptr<vfs::Backing> &backing) : backing(backing) {
|
||||
NroLoader::NroLoader(std::shared_ptr<vfs::Backing> pBacking) : backing(std::move(pBacking)) {
|
||||
header = backing->Read<NroHeader>();
|
||||
|
||||
if (header.magic != util::MakeMagic<u32>("NRO0"))
|
||||
@ -44,7 +44,7 @@ namespace skyline::loader {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void *NroLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
void *NroLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) {
|
||||
Executable executable{};
|
||||
|
||||
executable.text.contents = GetSegment(header.text);
|
||||
|
@ -68,10 +68,10 @@ namespace skyline::loader {
|
||||
std::vector<u8> GetSegment(const NroSegmentHeader &segment);
|
||||
|
||||
public:
|
||||
NroLoader(const std::shared_ptr<vfs::Backing> &backing);
|
||||
NroLoader(std::shared_ptr<vfs::Backing> backing);
|
||||
|
||||
std::vector<u8> GetIcon();
|
||||
std::vector<u8> GetIcon() override;
|
||||
|
||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) override;
|
||||
};
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "nso.h"
|
||||
|
||||
namespace skyline::loader {
|
||||
NsoLoader::NsoLoader(const std::shared_ptr<vfs::Backing> &backing) : backing(backing) {
|
||||
NsoLoader::NsoLoader(std::shared_ptr<vfs::Backing> pBacking) : backing(std::move(pBacking)) {
|
||||
u32 magic{backing->Read<u32>()};
|
||||
|
||||
if (magic != util::MakeMagic<u32>("NSO0"))
|
||||
@ -29,7 +29,7 @@ namespace skyline::loader {
|
||||
return outputBuffer;
|
||||
}
|
||||
|
||||
Loader::ExecutableLoadInfo NsoLoader::LoadNso(Loader *loader, const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state, size_t offset, const std::string &name) {
|
||||
Loader::ExecutableLoadInfo NsoLoader::LoadNso(Loader *loader, const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state, size_t offset, const std::string &name) {
|
||||
auto header{backing->Read<NsoHeader>()};
|
||||
|
||||
if (header.magic != util::MakeMagic<u32>("NSO0"))
|
||||
@ -59,7 +59,7 @@ namespace skyline::loader {
|
||||
return loader->LoadExecutable(process, state, executable, offset, name);
|
||||
}
|
||||
|
||||
void *NsoLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
void *NsoLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) {
|
||||
state.process->memory.InitializeVmm(memory::AddressSpaceType::AddressSpace39Bit);
|
||||
auto loadInfo{LoadNso(this, backing, process, state)};
|
||||
state.process->memory.InitializeRegions(loadInfo.base, loadInfo.size);
|
||||
|
@ -78,7 +78,7 @@ namespace skyline::loader {
|
||||
static std::vector<u8> GetSegment(const std::shared_ptr<vfs::Backing> &backing, const NsoSegmentHeader &segment, u32 compressedSize);
|
||||
|
||||
public:
|
||||
NsoLoader(const std::shared_ptr<vfs::Backing> &backing);
|
||||
NsoLoader(std::shared_ptr<vfs::Backing> backing);
|
||||
|
||||
/**
|
||||
* @brief Loads an NSO into memory, offset by the given amount
|
||||
@ -87,8 +87,8 @@ namespace skyline::loader {
|
||||
* @param name An optional name for the NSO, used for symbol resolution
|
||||
* @return An ExecutableLoadInfo struct containing the load base and size
|
||||
*/
|
||||
static ExecutableLoadInfo LoadNso(Loader *loader, const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state, size_t offset = 0, const std::string &name = {});
|
||||
static ExecutableLoadInfo LoadNso(Loader *loader, const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state, size_t offset = 0, const std::string &name = {});
|
||||
|
||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) override;
|
||||
};
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace skyline::loader {
|
||||
auto root{nsp->OpenDirectory("", {false, true})};
|
||||
|
||||
for (const auto &entry : root->Read()) {
|
||||
if (entry.name.substr(entry.name.find_last_of(".") + 1) != "nca")
|
||||
if (entry.name.substr(entry.name.find_last_of('.') + 1) != "nca")
|
||||
continue;
|
||||
|
||||
try {
|
||||
@ -35,7 +35,7 @@ namespace skyline::loader {
|
||||
nacp.emplace(controlRomFs->OpenFile("control.nacp"));
|
||||
}
|
||||
|
||||
void *NspLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
void *NspLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) {
|
||||
process->npdm = vfs::NPDM(programNca->exeFs->OpenFile("main.npdm"), state);
|
||||
return NcaLoader::LoadExeFs(this, programNca->exeFs, process, state);
|
||||
}
|
||||
|
@ -24,8 +24,8 @@ namespace skyline::loader {
|
||||
public:
|
||||
NspLoader(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore);
|
||||
|
||||
std::vector<u8> GetIcon();
|
||||
std::vector<u8> GetIcon() override;
|
||||
|
||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
void *LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) override;
|
||||
};
|
||||
}
|
||||
|
@ -19,13 +19,8 @@ namespace skyline::nce {
|
||||
struct Brk {
|
||||
/**
|
||||
* @brief Creates a BRK instruction with a specific immediate value, used for generating BRK opcodes
|
||||
* @param value The immediate value of the instruction
|
||||
*/
|
||||
constexpr Brk(u16 value) {
|
||||
sig0 = 0x0;
|
||||
this->value = value;
|
||||
sig1 = 0x6A1;
|
||||
}
|
||||
constexpr Brk(u16 value) : sig0(0x0), value(value), sig1(0x6A1) {}
|
||||
|
||||
constexpr bool Verify() {
|
||||
return (sig0 == 0x0 && sig1 == 0x6A1);
|
||||
@ -65,15 +60,7 @@ namespace skyline::nce {
|
||||
* @url https://developer.arm.com/docs/ddi0596/latest/base-instructions-alphabetic-order/mrs-move-system-register
|
||||
*/
|
||||
struct Mrs {
|
||||
/**
|
||||
* @param srcReg The source system register
|
||||
* @param dstReg The destination Xn register
|
||||
*/
|
||||
constexpr Mrs(u32 srcReg, registers::X dstReg) {
|
||||
this->srcReg = srcReg;
|
||||
this->destReg = dstReg;
|
||||
sig = 0xD53;
|
||||
}
|
||||
constexpr Mrs(u32 srcReg, registers::X destReg) : srcReg(srcReg), destReg(destReg), sig(0xD54) {}
|
||||
|
||||
constexpr bool Verify() {
|
||||
return (sig == 0xD53);
|
||||
@ -115,12 +102,9 @@ namespace skyline::nce {
|
||||
struct B {
|
||||
public:
|
||||
/**
|
||||
* @param offset The relative offset to branch to (In 32-bit units)
|
||||
* @param negate The direction of the supplied offset
|
||||
*/
|
||||
constexpr B(i64 offset, bool negate = false) {
|
||||
this->offset = negate ? -offset : offset;
|
||||
sig = 0x5;
|
||||
}
|
||||
constexpr B(i64 offset, bool negate = false) : offset(negate ? -offset : offset), sig(0x5) {}
|
||||
|
||||
/**
|
||||
* @return The offset encoded within the instruction in bytes
|
||||
@ -148,13 +132,7 @@ namespace skyline::nce {
|
||||
*/
|
||||
struct BL {
|
||||
public:
|
||||
/**
|
||||
* @param offset The relative offset to branch to (In 32-bit units)
|
||||
*/
|
||||
constexpr BL(i32 offset) {
|
||||
this->offset = offset;
|
||||
sig = 0x25;
|
||||
}
|
||||
constexpr BL(i32 offset) : offset(offset), sig(0x25) {}
|
||||
|
||||
/**
|
||||
* @return The offset encoded within the instruction in bytes
|
||||
@ -187,26 +165,14 @@ namespace skyline::nce {
|
||||
* @param imm16 The 16-bit value to store
|
||||
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
||||
*/
|
||||
constexpr Movz(registers::X destReg, u16 imm16, u8 shift = 0) {
|
||||
this->destReg = static_cast<u8>(destReg);
|
||||
this->imm16 = imm16;
|
||||
hw = shift;
|
||||
sig = 0xA5;
|
||||
sf = 1;
|
||||
}
|
||||
constexpr Movz(registers::X destReg, u16 imm16, u8 shift = 0) : destReg(static_cast<u8>(destReg)), imm16(imm16), hw(shift), sig(0xA5), sf(1) {}
|
||||
|
||||
/**
|
||||
* @param destReg The destination Wn register to store the value in
|
||||
* @param imm16 The 16-bit value to store
|
||||
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
||||
*/
|
||||
constexpr Movz(registers::W destReg, u16 imm16, u8 shift = 0) {
|
||||
this->destReg = static_cast<u8>(destReg);
|
||||
this->imm16 = imm16;
|
||||
hw = shift;
|
||||
sig = 0xA5;
|
||||
sf = 0;
|
||||
}
|
||||
constexpr Movz(registers::W destReg, u16 imm16, u8 shift = 0) : destReg(static_cast<u8>(destReg)), imm16(imm16), hw(shift), sig(0xA5), sf(0) {}
|
||||
|
||||
/**
|
||||
* @return The shift encoded within the instruction in bytes
|
||||
@ -242,26 +208,14 @@ namespace skyline::nce {
|
||||
* @param imm16 The 16-bit value to store
|
||||
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
||||
*/
|
||||
constexpr Movk(registers::X destReg, u16 imm16, u8 shift = 0) {
|
||||
this->destReg = static_cast<u8>(destReg);
|
||||
this->imm16 = imm16;
|
||||
hw = shift;
|
||||
sig = 0xE5;
|
||||
sf = 1;
|
||||
}
|
||||
constexpr Movk(registers::X destReg, u16 imm16, u8 shift = 0) : destReg(static_cast<u8>(destReg)), imm16(imm16), hw(shift), sig(0xE5), sf(1) {}
|
||||
|
||||
/**
|
||||
* @param destReg The destination Wn register to store the value in
|
||||
* @param imm16 The 16-bit value to store
|
||||
* @param shift The offset (in units of 16-bits) in the register to store the value at
|
||||
*/
|
||||
constexpr Movk(registers::W destReg, u16 imm16, u8 shift = 0) {
|
||||
this->destReg = static_cast<u8>(destReg);
|
||||
this->imm16 = imm16;
|
||||
hw = shift;
|
||||
sig = 0xE5;
|
||||
sf = 0;
|
||||
}
|
||||
constexpr Movk(registers::W destReg, u16 imm16, u8 shift = 0) : destReg(static_cast<u8>(destReg)), imm16(imm16), hw(shift), sig(0xE5), sf(0) {}
|
||||
|
||||
/**
|
||||
* @return The shift encoded within the instruction in bytes
|
||||
@ -329,28 +283,14 @@ namespace skyline::nce {
|
||||
* @param destReg The destination Xn register to store the value in
|
||||
* @param srcReg The source Xn register to retrieve the value from
|
||||
*/
|
||||
constexpr Mov(registers::X destReg, registers::X srcReg) {
|
||||
this->destReg = static_cast<u8>(destReg);
|
||||
sig0 = 0x1F;
|
||||
imm = 0;
|
||||
this->srcReg = static_cast<u8>(srcReg);
|
||||
sig1 = 0x150;
|
||||
sf = 1;
|
||||
}
|
||||
constexpr Mov(registers::X destReg, registers::X srcReg) : destReg(static_cast<u8>(destReg)), sig0(0x1F), imm(0), srcReg(static_cast<u8>(srcReg)), sig1(0x150), sf(1) {}
|
||||
|
||||
/**
|
||||
* @brief Creates a MOV instruction
|
||||
* @param destReg The destination Wn register to store the value in
|
||||
* @param srcReg The source Wn register to retrieve the value from
|
||||
*/
|
||||
constexpr Mov(registers::W destReg, registers::W srcReg) {
|
||||
this->destReg = static_cast<u8>(destReg);
|
||||
sig0 = 0x1F;
|
||||
imm = 0;
|
||||
this->srcReg = static_cast<u8>(srcReg);
|
||||
sig1 = 0x150;
|
||||
sf = 0;
|
||||
}
|
||||
constexpr Mov(registers::W destReg, registers::W srcReg) : destReg(static_cast<u8>(destReg)), sig0(0x1F), imm(0), srcReg(static_cast<u8>(srcReg)), sig1(0x150), sf(0) {}
|
||||
|
||||
constexpr bool Verify() {
|
||||
return (sig0 == 0x1F) && (sig1 == 0x150);
|
||||
|
@ -12,20 +12,20 @@
|
||||
#include "os.h"
|
||||
|
||||
namespace skyline::kernel {
|
||||
OS::OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, const std::string &appFilesPath) : state(this, jvmManager, settings, logger), serviceManager(state), appFilesPath(appFilesPath) {}
|
||||
OS::OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, std::string appFilesPath) : state(this, jvmManager, settings, logger), serviceManager(state), appFilesPath(std::move(appFilesPath)) {}
|
||||
|
||||
void OS::Execute(int romFd, loader::RomFormat romType) {
|
||||
auto romFile{std::make_shared<vfs::OsBacking>(romFd)};
|
||||
auto keyStore{std::make_shared<crypto::KeyStore>(appFilesPath)};
|
||||
|
||||
state.loader = [=]() -> std::shared_ptr<loader::Loader> {
|
||||
state.loader = [&]() -> std::shared_ptr<loader::Loader> {
|
||||
switch (romType) {
|
||||
case loader::RomFormat::NRO:
|
||||
return std::make_shared<loader::NroLoader>(romFile);
|
||||
return std::make_shared<loader::NroLoader>(std::move(romFile));
|
||||
case loader::RomFormat::NSO:
|
||||
return std::make_shared<loader::NsoLoader>(romFile);
|
||||
return std::make_shared<loader::NsoLoader>(std::move(romFile));
|
||||
case loader::RomFormat::NCA:
|
||||
return std::make_shared<loader::NcaLoader>(romFile, keyStore);
|
||||
return std::make_shared<loader::NcaLoader>(std::move(romFile), std::move(keyStore));
|
||||
case loader::RomFormat::NSP:
|
||||
return std::make_shared<loader::NspLoader>(romFile, keyStore);
|
||||
default:
|
||||
|
@ -21,7 +21,7 @@ namespace skyline::kernel {
|
||||
* @param settings An instance of the Settings class
|
||||
* @param window The ANativeWindow object to draw the screen to
|
||||
*/
|
||||
OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, const std::string &appFilesPath);
|
||||
OS(std::shared_ptr<JvmManager> &jvmManager, std::shared_ptr<Logger> &logger, std::shared_ptr<Settings> &settings, std::string appFilesPath);
|
||||
|
||||
/**
|
||||
* @brief Execute a particular ROM file
|
||||
|
@ -28,7 +28,7 @@ namespace skyline::service::am {
|
||||
* @brief Writes an object to the storage
|
||||
*/
|
||||
template<typename ValueType>
|
||||
inline void Push(const ValueType &value) {
|
||||
void Push(const ValueType &value) {
|
||||
if (offset + sizeof(ValueType) > content.size())
|
||||
throw exception("The supplied value cannot fit into the IStorage");
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "IStorageAccessor.h"
|
||||
|
||||
namespace skyline::service::am {
|
||||
IStorageAccessor::IStorageAccessor(const DeviceState &state, ServiceManager &manager, std::shared_ptr<IStorage> parent) : parent(parent), BaseService(state, manager) {}
|
||||
IStorageAccessor::IStorageAccessor(const DeviceState &state, ServiceManager &manager, std::shared_ptr<IStorage> parent) : parent(std::move(parent)), BaseService(state, manager) {}
|
||||
|
||||
Result IStorageAccessor::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
response.Push<i64>(parent->content.size());
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
namespace skyline::service::audio {
|
||||
IAudioOut::IAudioOut(const DeviceState &state, ServiceManager &manager, u8 channelCount, u32 sampleRate) : sampleRate(sampleRate), channelCount(channelCount), releaseEvent(std::make_shared<type::KEvent>(state, false)), BaseService(state, manager) {
|
||||
track = state.audio->OpenTrack(channelCount, constant::SampleRate, [this]() { this->releaseEvent->Signal(); });
|
||||
track = state.audio->OpenTrack(channelCount, constant::SampleRate, [this]() { releaseEvent->Signal(); });
|
||||
}
|
||||
|
||||
IAudioOut::~IAudioOut() {
|
||||
|
@ -9,7 +9,7 @@
|
||||
namespace skyline {
|
||||
namespace constant {
|
||||
constexpr std::string_view DefaultAudioOutName{"DeviceOut"}; //!< The default audio output device name
|
||||
};
|
||||
}
|
||||
|
||||
namespace service::audio {
|
||||
/**
|
||||
|
@ -7,7 +7,7 @@
|
||||
namespace skyline::service::audio::IAudioRenderer {
|
||||
IAudioRenderer::IAudioRenderer(const DeviceState &state, ServiceManager &manager, AudioRendererParameters ¶meters)
|
||||
: systemEvent(std::make_shared<type::KEvent>(state, true)), parameters(parameters), BaseService(state, manager) {
|
||||
track = state.audio->OpenTrack(constant::ChannelCount, constant::SampleRate, [&]() {systemEvent->Signal();});
|
||||
track = state.audio->OpenTrack(constant::ChannelCount, constant::SampleRate, [&]() { systemEvent->Signal(); });
|
||||
track->Start();
|
||||
|
||||
memoryPools.resize(parameters.effectCount + parameters.voiceCount * 4);
|
||||
|
@ -37,7 +37,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
public:
|
||||
EffectOut output{};
|
||||
|
||||
inline void ProcessInput(const EffectIn &input) {
|
||||
void ProcessInput(const EffectIn &input) {
|
||||
if (input.isNew)
|
||||
output.state = EffectState::New;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace skyline {
|
||||
constexpr u32 PerformanceMetricsDataFormatV2{5}; //!< The revision a new performance metrics format is used
|
||||
constexpr u32 VaradicCommandBufferSize{5}; //!< The revision support for varying command buffer sizes was added
|
||||
constexpr u32 ElapsedFrameCount{5}; //!< The revision support for counting elapsed frames was added
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace service::audio::IAudioRenderer {
|
||||
@ -42,7 +42,7 @@ namespace skyline {
|
||||
* @brief Extracts the audren revision from the magic and sets the behaviour revision to it
|
||||
* @param revision The revision magic from guest
|
||||
*/
|
||||
inline void SetUserRevision(u32 revision) {
|
||||
void SetUserRevision(u32 revision) {
|
||||
userRevision = ExtractVersionFromRevision(revision);
|
||||
|
||||
if (userRevision > constant::SupportedRevision)
|
||||
@ -52,35 +52,35 @@ namespace skyline {
|
||||
/**
|
||||
* @return Whether the splitter is supported
|
||||
*/
|
||||
inline bool SplitterSupported() {
|
||||
bool SplitterSupported() {
|
||||
return userRevision >= constant::supportTags::Splitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the splitter is fixed
|
||||
*/
|
||||
inline bool SplitterBugFixed() {
|
||||
bool SplitterBugFixed() {
|
||||
return userRevision >= constant::supportTags::SplitterBugFix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the new performance metrics format is used
|
||||
*/
|
||||
inline bool UsesPerformanceMetricDataFormatV2() {
|
||||
bool UsesPerformanceMetricDataFormatV2() {
|
||||
return userRevision >= constant::supportTags::PerformanceMetricsDataFormatV2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether varying command buffer sizes are supported
|
||||
*/
|
||||
inline bool VaradicCommandBufferSizeSupported() {
|
||||
bool VaradicCommandBufferSizeSupported() {
|
||||
return userRevision >= constant::supportTags::VaradicCommandBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether elapsed frame counting is supported
|
||||
*/
|
||||
inline bool ElapsedFrameCountSupported() {
|
||||
bool ElapsedFrameCountSupported() {
|
||||
return userRevision >= constant::supportTags::ElapsedFrameCount;
|
||||
}
|
||||
};
|
||||
|
@ -45,7 +45,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
std::vector<std::array<i16, 2>> adpcmCoefficients(input.adpcmCoeffsSize / (sizeof(u16) * 2));
|
||||
span(adpcmCoefficients).copy_from(span(input.adpcmCoeffs, input.adpcmCoeffsSize / sizeof(u32)));
|
||||
|
||||
adpcmDecoder = skyline::audio::AdpcmDecoder(adpcmCoefficients);
|
||||
adpcmDecoder = skyline::audio::AdpcmDecoder(std::move(adpcmCoefficients));
|
||||
}
|
||||
|
||||
SetWaveBufferIndex(static_cast<u8>(input.baseWaveBufferIndex));
|
||||
|
@ -122,7 +122,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
/**
|
||||
* @return If the voice is currently playable
|
||||
*/
|
||||
inline bool Playable() {
|
||||
bool Playable() {
|
||||
return acquired && playbackState == skyline::audio::AudioOutState::Started && waveBuffers[bufferIndex].size != 0;
|
||||
}
|
||||
};
|
||||
|
@ -10,7 +10,7 @@
|
||||
#define SERVICE_DECL_AUTO(name, value) decltype(value) name = value
|
||||
#define SERVICE_DECL(...) \
|
||||
SERVICE_DECL_AUTO(functions, frz::make_unordered_map({__VA_ARGS__})); \
|
||||
std::pair<std::function<Result(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>, std::string_view> GetServiceFunction(u32 id) { \
|
||||
std::pair<std::function<Result(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>, std::string_view> GetServiceFunction(u32 id) override { \
|
||||
auto& function{functions.at(id)}; \
|
||||
return std::make_pair(std::bind(function.first, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), function.second); \
|
||||
}
|
||||
@ -63,6 +63,6 @@ namespace skyline::service {
|
||||
/**
|
||||
* @brief Handles an IPC Request to a service
|
||||
*/
|
||||
Result HandleRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);;
|
||||
Result HandleRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||
};
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace skyline::service::nvdrv {
|
||||
/**
|
||||
* @brief Synchronizes the fence's value with its underlying syncpoint
|
||||
*/
|
||||
inline void UpdateValue(NvHostSyncpoint &hostSyncpoint) {
|
||||
void UpdateValue(NvHostSyncpoint &hostSyncpoint) {
|
||||
value = hostSyncpoint.UpdateMin(id);
|
||||
}
|
||||
};
|
||||
|
@ -43,7 +43,7 @@ namespace skyline::service {
|
||||
* @return A reference to an item from the top of data
|
||||
*/
|
||||
template<typename ValueType>
|
||||
inline ValueType &Pop() {
|
||||
ValueType &Pop() {
|
||||
ValueType &value{*reinterpret_cast<ValueType *>(data.data() + dataOffset)};
|
||||
dataOffset += sizeof(ValueType);
|
||||
return value;
|
||||
|
@ -21,7 +21,7 @@ namespace skyline::service::fssrv {
|
||||
u64 size;
|
||||
};
|
||||
|
||||
IDirectory::IDirectory(std::shared_ptr<vfs::Directory> backing, std::shared_ptr<vfs::FileSystem> backingFs, const DeviceState &state, ServiceManager &manager) : backing(backing), backingFs(backingFs), BaseService(state, manager) {}
|
||||
IDirectory::IDirectory(std::shared_ptr<vfs::Directory> backing, std::shared_ptr<vfs::FileSystem> backingFs, const DeviceState &state, ServiceManager &manager) : backing(std::move(backing)), backingFs(std::move(backingFs)), BaseService(state, manager) {}
|
||||
|
||||
Result IDirectory::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
auto entries{backing->Read()};
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "IFile.h"
|
||||
|
||||
namespace skyline::service::fssrv {
|
||||
IFile::IFile(std::shared_ptr<vfs::Backing> &backing, const DeviceState &state, ServiceManager &manager) : backing(backing), BaseService(state, manager) {}
|
||||
IFile::IFile(std::shared_ptr<vfs::Backing> backing, const DeviceState &state, ServiceManager &manager) : backing(std::move(backing)), BaseService(state, manager) {}
|
||||
|
||||
Result IFile::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
auto readOption{request.Pop<u32>()};
|
||||
|
@ -16,7 +16,7 @@ namespace skyline::service::fssrv {
|
||||
std::shared_ptr<vfs::Backing> backing;
|
||||
|
||||
public:
|
||||
IFile(std::shared_ptr<vfs::Backing> &backing, const DeviceState &state, ServiceManager &manager);
|
||||
IFile(std::shared_ptr<vfs::Backing> backing, const DeviceState &state, ServiceManager &manager);
|
||||
|
||||
/**
|
||||
* @brief Reads a buffer from a region of an IFile
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "IFileSystem.h"
|
||||
|
||||
namespace skyline::service::fssrv {
|
||||
IFileSystem::IFileSystem(std::shared_ptr<vfs::FileSystem> backing, const DeviceState &state, ServiceManager &manager) : backing(backing), BaseService(state, manager) {}
|
||||
IFileSystem::IFileSystem(std::shared_ptr<vfs::FileSystem> backing, const DeviceState &state, ServiceManager &manager) : backing(std::move(backing)), BaseService(state, manager) {}
|
||||
|
||||
Result IFileSystem::CreateFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
std::string path(request.inputBuf.at(0).as_string(true));
|
||||
@ -42,7 +42,7 @@ namespace skyline::service::fssrv {
|
||||
if (file == nullptr)
|
||||
return result::UnexpectedFailure;
|
||||
else
|
||||
manager.RegisterService(std::make_shared<IFile>(file, state, manager), session, response);
|
||||
manager.RegisterService(std::make_shared<IFile>(std::move(file), state, manager), session, response);
|
||||
|
||||
return {};
|
||||
}
|
||||
@ -56,7 +56,7 @@ namespace skyline::service::fssrv {
|
||||
auto listMode{request.Pop<vfs::Directory::ListMode>()};
|
||||
auto directory{backing->OpenDirectory(path, listMode)};
|
||||
|
||||
manager.RegisterService(std::make_shared<IDirectory>(directory, backing, state, manager), session, response);
|
||||
manager.RegisterService(std::make_shared<IDirectory>(std::move(directory), backing, state, manager), session, response);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ namespace skyline::service::fssrv {
|
||||
IFileSystemProxy::IFileSystemProxy(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
||||
|
||||
Result IFileSystemProxy::SetCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
process = request.Pop<pid_t>();
|
||||
process = request.Pop<u64>();
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ namespace skyline::service::fssrv {
|
||||
return "/nand/temp";
|
||||
default:
|
||||
throw exception("Unsupported savedata ID: {}", spaceId);
|
||||
};
|
||||
}
|
||||
}()};
|
||||
|
||||
switch (attribute.type) {
|
||||
@ -54,7 +54,7 @@ namespace skyline::service::fssrv {
|
||||
return fmt::format("{}/save/cache/{:016X}/", spaceIdStr, attribute.programId);
|
||||
default:
|
||||
throw exception("Unsupported savedata type: {}", attribute.type);
|
||||
};
|
||||
}
|
||||
}()};
|
||||
|
||||
manager.RegisterService(std::make_shared<IFileSystem>(std::make_shared<vfs::OsFileSystem>(state.os->appFilesPath + "/switch" + saveDataPath), state, manager), session, response);
|
||||
|
@ -48,7 +48,7 @@ namespace skyline::service::fssrv {
|
||||
*/
|
||||
class IFileSystemProxy : public BaseService {
|
||||
public:
|
||||
pid_t process{}; //!< The PID as set by SetCurrentProcess
|
||||
u64 process{}; //!< The PID as set by SetCurrentProcess
|
||||
|
||||
IFileSystemProxy(const DeviceState &state, ServiceManager &manager);
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "IStorage.h"
|
||||
|
||||
namespace skyline::service::fssrv {
|
||||
IStorage::IStorage(std::shared_ptr<vfs::Backing> &backing, const DeviceState &state, ServiceManager &manager) : backing(backing), BaseService(state, manager) {}
|
||||
IStorage::IStorage(std::shared_ptr<vfs::Backing> backing, const DeviceState &state, ServiceManager &manager) : backing(std::move(backing)), BaseService(state, manager) {}
|
||||
|
||||
Result IStorage::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
auto offset{request.Pop<i64>()};
|
||||
|
@ -16,7 +16,7 @@ namespace skyline::service::fssrv {
|
||||
std::shared_ptr<vfs::Backing> backing;
|
||||
|
||||
public:
|
||||
IStorage(std::shared_ptr<vfs::Backing> &backing, const DeviceState &state, ServiceManager &manager);
|
||||
IStorage(std::shared_ptr<vfs::Backing> backing, const DeviceState &state, ServiceManager &manager);
|
||||
|
||||
/**
|
||||
* @brief Reads a buffer from a region of an IStorage
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "GraphicBufferProducer.h"
|
||||
|
||||
namespace skyline::service::hosbinder {
|
||||
Buffer::Buffer(const GbpBuffer &gbpBuffer, const std::shared_ptr<gpu::Texture> &texture) : gbpBuffer(gbpBuffer), texture(texture) {}
|
||||
Buffer::Buffer(const GbpBuffer &gbpBuffer, std::shared_ptr<gpu::Texture> texture) : gbpBuffer(gbpBuffer), texture(std::move(texture)) {}
|
||||
|
||||
GraphicBufferProducer::GraphicBufferProducer(const DeviceState &state) : state(state) {}
|
||||
|
||||
@ -35,7 +35,7 @@ namespace skyline::service::hosbinder {
|
||||
std::optional<u32> slot{std::nullopt};
|
||||
while (!slot) {
|
||||
for (auto &buffer : queue) {
|
||||
if (buffer.second->status == BufferStatus::Free && (format ? buffer.second->gbpBuffer.format == format : true) && buffer.second->gbpBuffer.width == width && buffer.second->gbpBuffer.height == height && (buffer.second->gbpBuffer.usage & usage) == usage) {
|
||||
if (buffer.second->status == BufferStatus::Free && (format == 0 || buffer.second->gbpBuffer.format == format) && buffer.second->gbpBuffer.width == width && buffer.second->gbpBuffer.height == height && (buffer.second->gbpBuffer.usage & usage) == usage) {
|
||||
slot = buffer.first;
|
||||
buffer.second->status = BufferStatus::Dequeued;
|
||||
break;
|
||||
|
@ -50,7 +50,7 @@ namespace skyline::service::hosbinder {
|
||||
std::shared_ptr<gpu::Texture> texture;
|
||||
GbpBuffer gbpBuffer;
|
||||
|
||||
Buffer(const GbpBuffer &gbpBuffer, const std::shared_ptr<gpu::Texture> &texture);
|
||||
Buffer(const GbpBuffer &gbpBuffer, std::shared_ptr<gpu::Texture> texture);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -140,7 +140,6 @@ namespace skyline::service::nvdrv {
|
||||
else
|
||||
buffer = request.outputBuf[0];
|
||||
|
||||
|
||||
response.Push(device->HandleIoctl(cmd, device::IoctlType::Ioctl3, buffer, request.outputBuf.size() >= 2 ? request.outputBuf[1] : span<u8>()));
|
||||
return {};
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#define NVDEVICE_DECL_AUTO(name, value) decltype(value) name = value
|
||||
#define NVDEVICE_DECL(...) \
|
||||
NVDEVICE_DECL_AUTO(functions, frz::make_unordered_map({__VA_ARGS__})); \
|
||||
std::pair<std::function<NvStatus(IoctlType, span<u8>, span<u8>)>, std::string_view> GetIoctlFunction(u32 id) { \
|
||||
std::pair<std::function<NvStatus(IoctlType, span<u8>, span<u8>)>, std::string_view> GetIoctlFunction(u32 id) override { \
|
||||
auto& function{functions.at(id)}; \
|
||||
return std::make_pair(std::bind(function.first, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), function.second); \
|
||||
}
|
||||
@ -68,7 +68,7 @@ namespace skyline::service::nvdrv::device {
|
||||
const DeviceState &state;
|
||||
|
||||
public:
|
||||
inline NvDevice(const DeviceState &state) : state(state) {}
|
||||
NvDevice(const DeviceState &state) : state(state) {}
|
||||
|
||||
virtual ~NvDevice() = default;
|
||||
|
||||
@ -86,7 +86,7 @@ namespace skyline::service::nvdrv::device {
|
||||
*/
|
||||
NvStatus HandleIoctl(u32 cmd, IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
||||
|
||||
inline virtual std::shared_ptr<kernel::type::KEvent> QueryEvent(u32 eventId) {
|
||||
virtual std::shared_ptr<kernel::type::KEvent> QueryEvent(u32 eventId) {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
@ -88,7 +88,7 @@ namespace skyline::service::nvdrv::device {
|
||||
*/
|
||||
NvStatus SetUserData(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
||||
|
||||
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId);
|
||||
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId) override;
|
||||
|
||||
NVDEVICE_DECL(
|
||||
NVFUNC(0x4801, NvHostChannel, SetNvmapFd),
|
||||
|
@ -54,15 +54,14 @@ namespace skyline::service::nvdrv::device {
|
||||
event->ResetSignal();
|
||||
}
|
||||
|
||||
void SyncpointEvent::Wait(const std::shared_ptr<gpu::GPU> &gpuState, const Fence &fence) {
|
||||
void SyncpointEvent::Wait(const std::shared_ptr<gpu::GPU> &gpuState, const Fence &pFence) {
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
this->fence = fence;
|
||||
fence = pFence;
|
||||
state = State::Waiting;
|
||||
waiterId = gpuState->syncpoints.at(fence.id).RegisterWaiter(fence.value, [this] { Signal(); });
|
||||
}
|
||||
|
||||
|
||||
NvHostCtrl::NvHostCtrl(const DeviceState &state) : NvDevice(state) {}
|
||||
|
||||
u32 NvHostCtrl::FindFreeSyncpointEvent(u32 syncpointId) {
|
||||
|
@ -99,7 +99,7 @@ namespace skyline {
|
||||
*/
|
||||
NvStatus SyncpointRegisterEvent(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
||||
|
||||
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId);
|
||||
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId) override;
|
||||
|
||||
NVDEVICE_DECL(
|
||||
NVFUNC(0x001B, NvHostCtrl, GetConfig),
|
||||
|
@ -48,7 +48,7 @@ namespace skyline::service::nvdrv::device {
|
||||
*/
|
||||
NvStatus GetActiveSlotMask(IoctlType type, span<u8> buffer, span<u8> inlineBuffer);
|
||||
|
||||
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId);
|
||||
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId) override;
|
||||
|
||||
NVDEVICE_DECL(
|
||||
NVFUNC(0x4701, NvHostCtrlGpu, ZCullGetCtxSize),
|
||||
|
@ -39,7 +39,7 @@ namespace skyline::service::nvdrv::device {
|
||||
|
||||
NvMap(const DeviceState &state);
|
||||
|
||||
inline std::shared_ptr<NvMapObject> GetObject(u32 handle) {
|
||||
std::shared_ptr<NvMapObject> GetObject(u32 handle) {
|
||||
if (handle-- == 0)
|
||||
throw std::out_of_range("0 is an invalid nvmap handle");
|
||||
std::shared_lock lock(mapMutex);
|
||||
|
@ -62,7 +62,7 @@ namespace skyline::service::nvdrv {
|
||||
* @return A shared pointer to the device
|
||||
*/
|
||||
template<typename objectClass>
|
||||
inline std::shared_ptr<objectClass> GetDevice(u32 fd) {
|
||||
std::shared_ptr<objectClass> GetDevice(u32 fd) {
|
||||
return std::static_pointer_cast<objectClass>(GetDevice(fd));
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ namespace skyline::service {
|
||||
void RegisterService(std::shared_ptr<BaseService> serviceObject, type::KSession &session, ipc::IpcResponse &response);
|
||||
|
||||
template<typename ServiceType>
|
||||
inline void RegisterService(std::shared_ptr<ServiceType> serviceObject, type::KSession &session, ipc::IpcResponse &response) {
|
||||
void RegisterService(std::shared_ptr<ServiceType> serviceObject, type::KSession &session, ipc::IpcResponse &response) {
|
||||
RegisterService(std::static_pointer_cast<BaseService>(serviceObject), session, response);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ namespace skyline::service::timesrv {
|
||||
ITimeZoneService::ITimeZoneService(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {}
|
||||
|
||||
Result ITimeZoneService::ToCalendarTimeWithMyRule(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
auto& time{request.Pop<u64>()};
|
||||
auto &time{request.Pop<u64>()};
|
||||
auto calender{*std::gmtime(reinterpret_cast<const time_t *>(&time))};
|
||||
|
||||
CalendarTime calendarTime{
|
||||
|
@ -48,7 +48,7 @@ namespace skyline::vfs {
|
||||
* @brief Implicit casting for reading into spans of different types
|
||||
*/
|
||||
template<typename T, typename std::enable_if<!std::is_same_v<T, u8>, bool>::type = true>
|
||||
inline size_t Read(span <T> output, size_t offset = 0) {
|
||||
size_t Read(span <T> output, size_t offset = 0) {
|
||||
return Read(output.template cast<u8>(), offset);
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ namespace skyline::vfs {
|
||||
* @return The object that was read
|
||||
*/
|
||||
template<typename T>
|
||||
inline T Read(size_t offset = 0) {
|
||||
T Read(size_t offset = 0) {
|
||||
T object;
|
||||
Read(span(reinterpret_cast<u8 *>(&object), sizeof(T)), offset);
|
||||
return object;
|
||||
@ -80,7 +80,7 @@ namespace skyline::vfs {
|
||||
* @param offset The offset where the input should be written
|
||||
*/
|
||||
template<typename T>
|
||||
inline void WriteObject(const T &object, size_t offset = 0) {
|
||||
void WriteObject(const T &object, size_t offset = 0) {
|
||||
size_t size;
|
||||
if ((size = Write(span(reinterpret_cast<u8 *>(&object), sizeof(T)), offset)) != sizeof(T))
|
||||
throw exception("Object wasn't written fully into output backing: {}/{}", size, sizeof(T));
|
||||
|
@ -6,7 +6,7 @@
|
||||
namespace skyline::vfs {
|
||||
constexpr size_t SectorSize{0x10};
|
||||
|
||||
CtrEncryptedBacking::CtrEncryptedBacking(crypto::KeyStore::Key128 &ctr, crypto::KeyStore::Key128 &key, const std::shared_ptr<Backing> &backing, size_t baseOffset) : Backing({true, false, false}), ctr(ctr), cipher(key, MBEDTLS_CIPHER_AES_128_CTR), backing(backing), baseOffset(baseOffset) {}
|
||||
CtrEncryptedBacking::CtrEncryptedBacking(crypto::KeyStore::Key128 ctr, crypto::KeyStore::Key128 key, std::shared_ptr<Backing> backing, size_t baseOffset) : Backing({true, false, false}), ctr(ctr), cipher(key, MBEDTLS_CIPHER_AES_128_CTR), backing(std::move(backing)), baseOffset(baseOffset) {}
|
||||
|
||||
void CtrEncryptedBacking::UpdateCtr(u64 offset) {
|
||||
offset >>= 4;
|
||||
|
@ -25,7 +25,7 @@ namespace skyline::vfs {
|
||||
void UpdateCtr(u64 offset);
|
||||
|
||||
public:
|
||||
CtrEncryptedBacking(crypto::KeyStore::Key128 &ctr, crypto::KeyStore::Key128 &key, const std::shared_ptr<Backing> &backing, size_t baseOffset);
|
||||
CtrEncryptedBacking(crypto::KeyStore::Key128 ctr, crypto::KeyStore::Key128 key, std::shared_ptr<Backing> backing, size_t baseOffset);
|
||||
|
||||
size_t Read(span<u8> output, size_t offset = 0) override;
|
||||
};
|
||||
|
@ -61,7 +61,7 @@ namespace skyline::vfs {
|
||||
* @param path The path to the file
|
||||
* @return Whether the file exists
|
||||
*/
|
||||
inline bool FileExists(const std::string &path) {
|
||||
bool FileExists(const std::string &path) {
|
||||
auto entry{GetEntryType(path)};
|
||||
return entry && *entry == Directory::EntryType::File;
|
||||
}
|
||||
@ -71,7 +71,7 @@ namespace skyline::vfs {
|
||||
* @param path The path to the directory
|
||||
* @return Whether the directory exists
|
||||
*/
|
||||
inline bool DirectoryExists(const std::string &path) {
|
||||
bool DirectoryExists(const std::string &path) {
|
||||
auto entry{GetEntryType(path)};
|
||||
return entry && *entry == Directory::EntryType::Directory;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <crypto/aes_cipher.h>
|
||||
#include <loader/loader.h>
|
||||
|
||||
#include "ctr_encrypted_backing.h"
|
||||
#include "region_backing.h"
|
||||
#include "partition_filesystem.h"
|
||||
@ -13,7 +14,7 @@
|
||||
namespace skyline::vfs {
|
||||
using namespace loader;
|
||||
|
||||
NCA::NCA(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore) : backing(backing), keyStore(keyStore) {
|
||||
NCA::NCA(std::shared_ptr<vfs::Backing> pBacking, std::shared_ptr<crypto::KeyStore> pKeyStore) : backing(std::move(pBacking)), keyStore(std::move(pKeyStore)) {
|
||||
header = backing->Read<NcaHeader>();
|
||||
|
||||
if (header.magic != util::MakeMagic<u32>("NCA3")) {
|
||||
@ -116,7 +117,7 @@ namespace skyline::vfs {
|
||||
}
|
||||
|
||||
crypto::KeyStore::Key128 NCA::GetKeyAreaKey(NCA::NcaSectionEncryptionType type) {
|
||||
auto keyArea{[&](crypto::KeyStore::IndexedKeys128 &keys) {
|
||||
auto keyArea{[this, &type](crypto::KeyStore::IndexedKeys128 &keys) {
|
||||
u8 keyGeneration{GetKeyGeneration()};
|
||||
|
||||
auto &keyArea{keys[keyGeneration]};
|
||||
|
@ -193,7 +193,7 @@ namespace skyline {
|
||||
std::shared_ptr<Backing> romFs; //!< The backing for this NCA's RomFS section
|
||||
NcaContentType contentType; //!< The content type of the NCA
|
||||
|
||||
NCA(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore);
|
||||
NCA(std::shared_ptr<vfs::Backing> backing, std::shared_ptr<crypto::KeyStore> keyStore);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace skyline {
|
||||
u32 size;
|
||||
|
||||
template<typename T>
|
||||
inline T Read(const std::shared_ptr<vfs::Backing> &backing, size_t baseOffset = 0) {
|
||||
T Read(const std::shared_ptr<vfs::Backing> &backing, size_t baseOffset = 0) {
|
||||
if (sizeof(T) > size)
|
||||
throw exception("Section size ({}) smaller than Read type size ({})", size, sizeof(T));
|
||||
return backing->Read<T>(baseOffset + offset);
|
||||
|
@ -42,11 +42,11 @@ namespace skyline::vfs {
|
||||
return static_cast<size_t>(ret);
|
||||
}
|
||||
|
||||
void OsBacking::Resize(size_t size) {
|
||||
int ret{ftruncate(fd, size)};
|
||||
void OsBacking::Resize(size_t pSize) {
|
||||
int ret{ftruncate(fd, pSize)};
|
||||
if (ret < 0)
|
||||
throw exception("Failed to resize file: {}", strerror(errno));
|
||||
|
||||
this->size = size;
|
||||
size = pSize;
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ namespace skyline::vfs {
|
||||
return std::make_shared<OsFileSystemDirectory>(basePath + path, listMode);
|
||||
}
|
||||
|
||||
OsFileSystemDirectory::OsFileSystemDirectory(const std::string &path, Directory::ListMode listMode) : Directory(listMode), path(path) {}
|
||||
OsFileSystemDirectory::OsFileSystemDirectory(std::string path, Directory::ListMode listMode) : Directory(listMode), path(std::move(path)) {}
|
||||
|
||||
std::vector<Directory::Entry> OsFileSystemDirectory::Read() {
|
||||
if (!listMode.file && !listMode.directory)
|
||||
|
@ -35,7 +35,7 @@ namespace skyline::vfs {
|
||||
std::string path;
|
||||
|
||||
public:
|
||||
OsFileSystemDirectory(const std::string &path, ListMode listMode);
|
||||
OsFileSystemDirectory(std::string path, ListMode listMode);
|
||||
|
||||
std::vector<Entry> Read();
|
||||
};
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "partition_filesystem.h"
|
||||
|
||||
namespace skyline::vfs {
|
||||
PartitionFileSystem::PartitionFileSystem(std::shared_ptr<Backing> backing) : FileSystem(), backing(backing) {
|
||||
PartitionFileSystem::PartitionFileSystem(const std::shared_ptr<Backing> &backing) : FileSystem(), backing(backing) {
|
||||
header = backing->Read<FsHeader>();
|
||||
|
||||
if (header.magic == util::MakeMagic<u32>("PFS0"))
|
||||
@ -27,7 +27,7 @@ namespace skyline::vfs {
|
||||
auto entry{backing->Read<PartitionFileEntry>(entryOffset)};
|
||||
|
||||
std::string name(&stringTable[entry.stringTableOffset]);
|
||||
fileMap.emplace(name, std::move(entry));
|
||||
fileMap.emplace(name, entry);
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ namespace skyline::vfs {
|
||||
return std::make_shared<PartitionFileSystemDirectory>(fileList, listMode);
|
||||
}
|
||||
|
||||
PartitionFileSystemDirectory::PartitionFileSystemDirectory(const std::vector<Entry> &fileList, ListMode listMode) : Directory(listMode), fileList(fileList) {}
|
||||
PartitionFileSystemDirectory::PartitionFileSystemDirectory(std::vector<Entry> fileList, ListMode listMode) : Directory(listMode), fileList(std::move(fileList)) {}
|
||||
|
||||
std::vector<Directory::Entry> PartitionFileSystemDirectory::Read() {
|
||||
if (listMode.file)
|
||||
|
@ -40,7 +40,7 @@ namespace skyline::vfs {
|
||||
std::unordered_map<std::string, PartitionFileEntry> fileMap; //!< A map that maps file names to their corresponding entry
|
||||
|
||||
public:
|
||||
PartitionFileSystem(std::shared_ptr<Backing> backing);
|
||||
PartitionFileSystem(const std::shared_ptr<Backing> &backing);
|
||||
|
||||
std::shared_ptr<Backing> OpenFile(const std::string &path, Backing::Mode mode = {true, false, false});
|
||||
|
||||
@ -57,7 +57,7 @@ namespace skyline::vfs {
|
||||
std::vector<Entry> fileList; //!< A list of every file in the PFS root directory
|
||||
|
||||
public:
|
||||
PartitionFileSystemDirectory(const std::vector<Entry> &fileList, ListMode listMode);
|
||||
PartitionFileSystemDirectory(std::vector<Entry> fileList, ListMode listMode);
|
||||
|
||||
std::vector<Entry> Read();
|
||||
};
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "rom_filesystem.h"
|
||||
|
||||
namespace skyline::vfs {
|
||||
RomFileSystem::RomFileSystem(std::shared_ptr<Backing> backing) : FileSystem(), backing(backing) {
|
||||
RomFileSystem::RomFileSystem(std::shared_ptr<Backing> pBacking) : FileSystem(), backing(std::move(pBacking)) {
|
||||
header = backing->Read<RomFsHeader>();
|
||||
TraverseDirectory(0, "");
|
||||
}
|
||||
@ -30,7 +30,7 @@ namespace skyline::vfs {
|
||||
void RomFileSystem::TraverseDirectory(u32 offset, const std::string &path) {
|
||||
auto entry{backing->Read<RomFsDirectoryEntry>(header.dirMetaTableOffset + offset)};
|
||||
|
||||
std::string childPath{path};
|
||||
std::string childPath(path);
|
||||
if (entry.nameSize) {
|
||||
std::vector<char> name(entry.nameSize);
|
||||
backing->Read(span(name), header.dirMetaTableOffset + offset + sizeof(RomFsDirectoryEntry));
|
||||
@ -76,7 +76,7 @@ namespace skyline::vfs {
|
||||
}
|
||||
}
|
||||
|
||||
RomFileSystemDirectory::RomFileSystemDirectory(const std::shared_ptr<Backing> &backing, const RomFileSystem::RomFsHeader &header, const RomFileSystem::RomFsDirectoryEntry &ownEntry, ListMode listMode) : Directory(listMode), backing(backing), header(header), ownEntry(ownEntry) {}
|
||||
RomFileSystemDirectory::RomFileSystemDirectory(std::shared_ptr<Backing> backing, const RomFileSystem::RomFsHeader &header, const RomFileSystem::RomFsDirectoryEntry &ownEntry, ListMode listMode) : Directory(listMode), backing(std::move(backing)), header(header), ownEntry(ownEntry) {}
|
||||
|
||||
std::vector<RomFileSystemDirectory::Entry> RomFileSystemDirectory::Read() {
|
||||
std::vector<Entry> contents;
|
||||
|
@ -87,7 +87,7 @@ namespace skyline {
|
||||
std::shared_ptr<Backing> backing;
|
||||
|
||||
public:
|
||||
RomFileSystemDirectory(const std::shared_ptr<Backing> &backing, const RomFileSystem::RomFsHeader &header, const RomFileSystem::RomFsDirectoryEntry &ownEntry, ListMode listMode);
|
||||
RomFileSystemDirectory(std::shared_ptr<Backing> backing, const RomFileSystem::RomFsHeader &header, const RomFileSystem::RomFsDirectoryEntry &ownEntry, ListMode listMode);
|
||||
|
||||
std::vector<Entry> Read();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user