1
0
Fork 0
forked from suyu/suyu

Merge branch 'master' into tlds

This commit is contained in:
raven02 2018-09-19 19:53:11 +08:00 committed by GitHub
commit c8f9bbbf85
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
164 changed files with 1657 additions and 1068 deletions

View file

@ -35,12 +35,12 @@ Filter::Filter(double a0, double a1, double a2, double b0, double b1, double b2)
: a1(a1 / a0), a2(a2 / a0), b0(b0 / a0), b1(b1 / a0), b2(b2 / a0) {} : a1(a1 / a0), a2(a2 / a0), b0(b0 / a0), b1(b1 / a0), b2(b2 / a0) {}
void Filter::Process(std::vector<s16>& signal) { void Filter::Process(std::vector<s16>& signal) {
const size_t num_frames = signal.size() / 2; const std::size_t num_frames = signal.size() / 2;
for (size_t i = 0; i < num_frames; i++) { for (std::size_t i = 0; i < num_frames; i++) {
std::rotate(in.begin(), in.end() - 1, in.end()); std::rotate(in.begin(), in.end() - 1, in.end());
std::rotate(out.begin(), out.end() - 1, out.end()); std::rotate(out.begin(), out.end() - 1, out.end());
for (size_t ch = 0; ch < channel_count; ch++) { for (std::size_t ch = 0; ch < channel_count; ch++) {
in[0][ch] = signal[i * channel_count + ch]; in[0][ch] = signal[i * channel_count + ch];
out[0][ch] = b0 * in[0][ch] + b1 * in[1][ch] + b2 * in[2][ch] - a1 * out[1][ch] - out[0][ch] = b0 * in[0][ch] + b1 * in[1][ch] + b2 * in[2][ch] - a1 * out[1][ch] -
@ -54,14 +54,14 @@ void Filter::Process(std::vector<s16>& signal) {
/// Calculates the appropriate Q for each biquad in a cascading filter. /// Calculates the appropriate Q for each biquad in a cascading filter.
/// @param total_count The total number of biquads to be cascaded. /// @param total_count The total number of biquads to be cascaded.
/// @param index 0-index of the biquad to calculate the Q value for. /// @param index 0-index of the biquad to calculate the Q value for.
static double CascadingBiquadQ(size_t total_count, size_t index) { static double CascadingBiquadQ(std::size_t total_count, std::size_t index) {
const double pole = M_PI * (2 * index + 1) / (4.0 * total_count); const double pole = M_PI * (2 * index + 1) / (4.0 * total_count);
return 1.0 / (2.0 * std::cos(pole)); return 1.0 / (2.0 * std::cos(pole));
} }
CascadingFilter CascadingFilter::LowPass(double cutoff, size_t cascade_size) { CascadingFilter CascadingFilter::LowPass(double cutoff, std::size_t cascade_size) {
std::vector<Filter> cascade(cascade_size); std::vector<Filter> cascade(cascade_size);
for (size_t i = 0; i < cascade_size; i++) { for (std::size_t i = 0; i < cascade_size; i++) {
cascade[i] = Filter::LowPass(cutoff, CascadingBiquadQ(cascade_size, i)); cascade[i] = Filter::LowPass(cutoff, CascadingBiquadQ(cascade_size, i));
} }
return CascadingFilter{std::move(cascade)}; return CascadingFilter{std::move(cascade)};

View file

@ -30,7 +30,7 @@ public:
void Process(std::vector<s16>& signal); void Process(std::vector<s16>& signal);
private: private:
static constexpr size_t channel_count = 2; static constexpr std::size_t channel_count = 2;
/// Coefficients are in normalized form (a0 = 1.0). /// Coefficients are in normalized form (a0 = 1.0).
double a1, a2, b0, b1, b2; double a1, a2, b0, b1, b2;
@ -46,7 +46,7 @@ public:
/// Creates a cascading low-pass filter. /// Creates a cascading low-pass filter.
/// @param cutoff Determines the cutoff frequency. A value from 0.0 to 1.0. /// @param cutoff Determines the cutoff frequency. A value from 0.0 to 1.0.
/// @param cascade_size Number of biquads in cascade. /// @param cascade_size Number of biquads in cascade.
static CascadingFilter LowPass(double cutoff, size_t cascade_size); static CascadingFilter LowPass(double cutoff, std::size_t cascade_size);
/// Passthrough. /// Passthrough.
CascadingFilter(); CascadingFilter();

View file

@ -14,7 +14,7 @@
namespace AudioCore { namespace AudioCore {
/// The Lanczos kernel /// The Lanczos kernel
static double Lanczos(size_t a, double x) { static double Lanczos(std::size_t a, double x) {
if (x == 0.0) if (x == 0.0)
return 1.0; return 1.0;
const double px = M_PI * x; const double px = M_PI * x;
@ -37,15 +37,15 @@ std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input,
} }
state.nyquist.Process(input); state.nyquist.Process(input);
constexpr size_t taps = InterpolationState::lanczos_taps; constexpr std::size_t taps = InterpolationState::lanczos_taps;
const size_t num_frames = input.size() / 2; const std::size_t num_frames = input.size() / 2;
std::vector<s16> output; std::vector<s16> output;
output.reserve(static_cast<size_t>(input.size() / ratio + 4)); output.reserve(static_cast<std::size_t>(input.size() / ratio + 4));
double& pos = state.position; double& pos = state.position;
auto& h = state.history; auto& h = state.history;
for (size_t i = 0; i < num_frames; ++i) { for (std::size_t i = 0; i < num_frames; ++i) {
std::rotate(h.begin(), h.end() - 1, h.end()); std::rotate(h.begin(), h.end() - 1, h.end());
h[0][0] = input[i * 2 + 0]; h[0][0] = input[i * 2 + 0];
h[0][1] = input[i * 2 + 1]; h[0][1] = input[i * 2 + 1];
@ -53,7 +53,7 @@ std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input,
while (pos <= 1.0) { while (pos <= 1.0) {
double l = 0.0; double l = 0.0;
double r = 0.0; double r = 0.0;
for (size_t j = 0; j < h.size(); j++) { for (std::size_t j = 0; j < h.size(); j++) {
l += Lanczos(taps, pos + j - taps + 1) * h[j][0]; l += Lanczos(taps, pos + j - taps + 1) * h[j][0];
r += Lanczos(taps, pos + j - taps + 1) * h[j][1]; r += Lanczos(taps, pos + j - taps + 1) * h[j][1];
} }

View file

@ -12,8 +12,8 @@
namespace AudioCore { namespace AudioCore {
struct InterpolationState { struct InterpolationState {
static constexpr size_t lanczos_taps = 4; static constexpr std::size_t lanczos_taps = 4;
static constexpr size_t history_size = lanczos_taps * 2 - 1; static constexpr std::size_t history_size = lanczos_taps * 2 - 1;
double current_ratio = 0.0; double current_ratio = 0.0;
CascadingFilter nyquist; CascadingFilter nyquist;

View file

@ -39,7 +39,8 @@ StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, std::string&&
sink->AcquireSinkStream(sample_rate, num_channels, name), std::move(name)); sink->AcquireSinkStream(sample_rate, num_channels, name), std::move(name));
} }
std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) { std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream,
std::size_t max_count) {
return stream->GetTagsAndReleaseBuffers(max_count); return stream->GetTagsAndReleaseBuffers(max_count);
} }

View file

@ -25,7 +25,7 @@ public:
Stream::ReleaseCallback&& release_callback); Stream::ReleaseCallback&& release_callback);
/// Returns a vector of recently released buffers specified by tag for the specified stream /// Returns a vector of recently released buffers specified by tag for the specified stream
std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count); std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream, std::size_t max_count);
/// Starts an audio stream for playback /// Starts an audio stream for playback
void StartStream(StreamPtr stream); void StartStream(StreamPtr stream);

View file

@ -3,9 +3,12 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "audio_core/algorithm/interpolate.h" #include "audio_core/algorithm/interpolate.h"
#include "audio_core/audio_out.h"
#include "audio_core/audio_renderer.h" #include "audio_core/audio_renderer.h"
#include "audio_core/codec.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/hle/kernel/event.h"
#include "core/memory.h" #include "core/memory.h"
namespace AudioCore { namespace AudioCore {
@ -13,6 +16,41 @@ namespace AudioCore {
constexpr u32 STREAM_SAMPLE_RATE{48000}; constexpr u32 STREAM_SAMPLE_RATE{48000};
constexpr u32 STREAM_NUM_CHANNELS{2}; constexpr u32 STREAM_NUM_CHANNELS{2};
class AudioRenderer::VoiceState {
public:
bool IsPlaying() const {
return is_in_use && info.play_state == PlayState::Started;
}
const VoiceOutStatus& GetOutStatus() const {
return out_status;
}
const VoiceInfo& GetInfo() const {
return info;
}
VoiceInfo& Info() {
return info;
}
void SetWaveIndex(std::size_t index);
std::vector<s16> DequeueSamples(std::size_t sample_count);
void UpdateState();
void RefreshBuffer();
private:
bool is_in_use{};
bool is_refresh_pending{};
std::size_t wave_index{};
std::size_t offset{};
Codec::ADPCMState adpcm_state{};
InterpolationState interp_state{};
std::vector<s16> samples;
VoiceOutStatus out_status{};
VoiceInfo info{};
};
AudioRenderer::AudioRenderer(AudioRendererParameter params, AudioRenderer::AudioRenderer(AudioRendererParameter params,
Kernel::SharedPtr<Kernel::Event> buffer_event) Kernel::SharedPtr<Kernel::Event> buffer_event)
: worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count) { : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count) {
@ -27,6 +65,8 @@ AudioRenderer::AudioRenderer(AudioRendererParameter params,
QueueMixedBuffer(2); QueueMixedBuffer(2);
} }
AudioRenderer::~AudioRenderer() = default;
u32 AudioRenderer::GetSampleRate() const { u32 AudioRenderer::GetSampleRate() const {
return worker_params.sample_rate; return worker_params.sample_rate;
} }
@ -52,7 +92,7 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
memory_pool_count * sizeof(MemoryPoolInfo)); memory_pool_count * sizeof(MemoryPoolInfo));
// Copy VoiceInfo structs // Copy VoiceInfo structs
size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size + std::size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size +
config.voice_resource_size}; config.voice_resource_size};
for (auto& voice : voices) { for (auto& voice : voices) {
std::memcpy(&voice.Info(), input_params.data() + offset, sizeof(VoiceInfo)); std::memcpy(&voice.Info(), input_params.data() + offset, sizeof(VoiceInfo));
@ -72,7 +112,7 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
// Update memory pool state // Update memory pool state
std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); std::vector<MemoryPoolEntry> memory_pool(memory_pool_count);
for (size_t index = 0; index < memory_pool.size(); ++index) { for (std::size_t index = 0; index < memory_pool.size(); ++index) {
if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) { if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) {
memory_pool[index].state = MemoryPoolStates::Attached; memory_pool[index].state = MemoryPoolStates::Attached;
} else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) { } else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) {
@ -93,7 +133,7 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
response_data.memory_pools_size); response_data.memory_pools_size);
// Copy output voice status // Copy output voice status
size_t voice_out_status_offset{sizeof(UpdateDataHeader) + response_data.memory_pools_size}; std::size_t voice_out_status_offset{sizeof(UpdateDataHeader) + response_data.memory_pools_size};
for (const auto& voice : voices) { for (const auto& voice : voices) {
std::memcpy(output_params.data() + voice_out_status_offset, &voice.GetOutStatus(), std::memcpy(output_params.data() + voice_out_status_offset, &voice.GetOutStatus(),
sizeof(VoiceOutStatus)); sizeof(VoiceOutStatus));
@ -103,12 +143,12 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
return output_params; return output_params;
} }
void AudioRenderer::VoiceState::SetWaveIndex(size_t index) { void AudioRenderer::VoiceState::SetWaveIndex(std::size_t index) {
wave_index = index & 3; wave_index = index & 3;
is_refresh_pending = true; is_refresh_pending = true;
} }
std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(size_t sample_count) { std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_count) {
if (!IsPlaying()) { if (!IsPlaying()) {
return {}; return {};
} }
@ -117,9 +157,9 @@ std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(size_t sample_count)
RefreshBuffer(); RefreshBuffer();
} }
const size_t max_size{samples.size() - offset}; const std::size_t max_size{samples.size() - offset};
const size_t dequeue_offset{offset}; const std::size_t dequeue_offset{offset};
size_t size{sample_count * STREAM_NUM_CHANNELS}; std::size_t size{sample_count * STREAM_NUM_CHANNELS};
if (size > max_size) { if (size > max_size) {
size = max_size; size = max_size;
} }
@ -184,7 +224,7 @@ void AudioRenderer::VoiceState::RefreshBuffer() {
case 1: case 1:
// 1 channel is upsampled to 2 channel // 1 channel is upsampled to 2 channel
samples.resize(new_samples.size() * 2); samples.resize(new_samples.size() * 2);
for (size_t index = 0; index < new_samples.size(); ++index) { for (std::size_t index = 0; index < new_samples.size(); ++index) {
samples[index * 2] = new_samples[index]; samples[index * 2] = new_samples[index];
samples[index * 2 + 1] = new_samples[index]; samples[index * 2 + 1] = new_samples[index];
} }
@ -210,7 +250,7 @@ static constexpr s16 ClampToS16(s32 value) {
} }
void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
constexpr size_t BUFFER_SIZE{512}; constexpr std::size_t BUFFER_SIZE{512};
std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels()); std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels());
for (auto& voice : voices) { for (auto& voice : voices) {
@ -218,7 +258,7 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
continue; continue;
} }
size_t offset{}; std::size_t offset{};
s64 samples_remaining{BUFFER_SIZE}; s64 samples_remaining{BUFFER_SIZE};
while (samples_remaining > 0) { while (samples_remaining > 0) {
const std::vector<s16> samples{voice.DequeueSamples(samples_remaining)}; const std::vector<s16> samples{voice.DequeueSamples(samples_remaining)};

View file

@ -8,16 +8,20 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "audio_core/algorithm/interpolate.h"
#include "audio_core/audio_out.h"
#include "audio_core/codec.h"
#include "audio_core/stream.h" #include "audio_core/stream.h"
#include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/swap.h" #include "common/swap.h"
#include "core/hle/kernel/event.h" #include "core/hle/kernel/object.h"
namespace Kernel {
class Event;
}
namespace AudioCore { namespace AudioCore {
class AudioOut;
enum class PlayState : u8 { enum class PlayState : u8 {
Started = 0, Started = 0,
Stopped = 1, Stopped = 1,
@ -158,6 +162,8 @@ static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size
class AudioRenderer { class AudioRenderer {
public: public:
AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event); AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event);
~AudioRenderer();
std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params); std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params);
void QueueMixedBuffer(Buffer::Tag tag); void QueueMixedBuffer(Buffer::Tag tag);
void ReleaseAndQueueBuffers(); void ReleaseAndQueueBuffers();
@ -166,45 +172,12 @@ public:
u32 GetMixBufferCount() const; u32 GetMixBufferCount() const;
private: private:
class VoiceState { class VoiceState;
public:
bool IsPlaying() const {
return is_in_use && info.play_state == PlayState::Started;
}
const VoiceOutStatus& GetOutStatus() const {
return out_status;
}
const VoiceInfo& GetInfo() const {
return info;
}
VoiceInfo& Info() {
return info;
}
void SetWaveIndex(size_t index);
std::vector<s16> DequeueSamples(size_t sample_count);
void UpdateState();
void RefreshBuffer();
private:
bool is_in_use{};
bool is_refresh_pending{};
size_t wave_index{};
size_t offset{};
Codec::ADPCMState adpcm_state{};
InterpolationState interp_state{};
std::vector<s16> samples;
VoiceOutStatus out_status{};
VoiceInfo info{};
};
AudioRendererParameter worker_params; AudioRendererParameter worker_params;
Kernel::SharedPtr<Kernel::Event> buffer_event; Kernel::SharedPtr<Kernel::Event> buffer_event;
std::vector<VoiceState> voices; std::vector<VoiceState> voices;
std::unique_ptr<AudioCore::AudioOut> audio_out; std::unique_ptr<AudioOut> audio_out;
AudioCore::StreamPtr stream; AudioCore::StreamPtr stream;
}; };

View file

@ -8,27 +8,27 @@
namespace AudioCore::Codec { namespace AudioCore::Codec {
std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff, std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff,
ADPCMState& state) { ADPCMState& state) {
// GC-ADPCM with scale factor and variable coefficients. // GC-ADPCM with scale factor and variable coefficients.
// Frames are 8 bytes long containing 14 samples each. // Frames are 8 bytes long containing 14 samples each.
// Samples are 4 bits (one nibble) long. // Samples are 4 bits (one nibble) long.
constexpr size_t FRAME_LEN = 8; constexpr std::size_t FRAME_LEN = 8;
constexpr size_t SAMPLES_PER_FRAME = 14; constexpr std::size_t SAMPLES_PER_FRAME = 14;
constexpr std::array<int, 16> SIGNED_NIBBLES = { constexpr std::array<int, 16> SIGNED_NIBBLES = {
{0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}};
const size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME; const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME;
const size_t ret_size = const std::size_t ret_size =
sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two. sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two.
std::vector<s16> ret(ret_size); std::vector<s16> ret(ret_size);
int yn1 = state.yn1, yn2 = state.yn2; int yn1 = state.yn1, yn2 = state.yn2;
const size_t NUM_FRAMES = const std::size_t NUM_FRAMES =
(sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up. (sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up.
for (size_t framei = 0; framei < NUM_FRAMES; framei++) { for (std::size_t framei = 0; framei < NUM_FRAMES; framei++) {
const int frame_header = data[framei * FRAME_LEN]; const int frame_header = data[framei * FRAME_LEN];
const int scale = 1 << (frame_header & 0xF); const int scale = 1 << (frame_header & 0xF);
const int idx = (frame_header >> 4) & 0x7; const int idx = (frame_header >> 4) & 0x7;
@ -53,9 +53,9 @@ std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coef
return static_cast<s16>(val); return static_cast<s16>(val);
}; };
size_t outputi = framei * SAMPLES_PER_FRAME; std::size_t outputi = framei * SAMPLES_PER_FRAME;
size_t datai = framei * FRAME_LEN + 1; std::size_t datai = framei * FRAME_LEN + 1;
for (size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) { for (std::size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) {
const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]); const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]);
ret[outputi] = sample1; ret[outputi] = sample1;
outputi++; outputi++;

View file

@ -38,7 +38,7 @@ using ADPCM_Coeff = std::array<s16, 16>;
* @param state ADPCM state, this is updated with new state * @param state ADPCM state, this is updated with new state
* @return Decoded stereo signed PCM16 data, sample_count in length * @return Decoded stereo signed PCM16 data, sample_count in length
*/ */
std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff, std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff,
ADPCMState& state); ADPCMState& state);
}; // namespace AudioCore::Codec }; // namespace AudioCore::Codec

View file

@ -63,8 +63,8 @@ public:
// Downsample 6 channels to 2 // Downsample 6 channels to 2
std::vector<s16> buf; std::vector<s16> buf;
buf.reserve(samples.size() * num_channels / source_num_channels); buf.reserve(samples.size() * num_channels / source_num_channels);
for (size_t i = 0; i < samples.size(); i += source_num_channels) { for (std::size_t i = 0; i < samples.size(); i += source_num_channels) {
for (size_t ch = 0; ch < num_channels; ch++) { for (std::size_t ch = 0; ch < num_channels; ch++) {
buf.push_back(samples[i + ch]); buf.push_back(samples[i + ch]);
} }
} }
@ -75,7 +75,7 @@ public:
queue.Push(samples); queue.Push(samples);
} }
size_t SamplesInQueue(u32 num_channels) const override { std::size_t SamplesInQueue(u32 num_channels) const override {
if (!ctx) if (!ctx)
return 0; return 0;
@ -119,9 +119,9 @@ CubebSink::CubebSink(std::string target_device_name) {
LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported"); LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
} else { } else {
const auto collection_end{collection.device + collection.count}; const auto collection_end{collection.device + collection.count};
const auto device{std::find_if(collection.device, collection_end, const auto device{
[&](const cubeb_device_info& device) { std::find_if(collection.device, collection_end, [&](const cubeb_device_info& info) {
return target_device_name == device.friendly_name; return target_device_name == info.friendly_name;
})}; })};
if (device != collection_end) { if (device != collection_end) {
output_device = device->devid; output_device = device->devid;
@ -159,15 +159,16 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const
return {}; return {};
} }
const size_t num_channels = impl->GetNumChannels(); const std::size_t num_channels = impl->GetNumChannels();
const size_t samples_to_write = num_channels * num_frames; const std::size_t samples_to_write = num_channels * num_frames;
size_t samples_written; std::size_t samples_written;
if (Settings::values.enable_audio_stretching) { if (Settings::values.enable_audio_stretching) {
const std::vector<s16> in{impl->queue.Pop()}; const std::vector<s16> in{impl->queue.Pop()};
const size_t num_in{in.size() / num_channels}; const std::size_t num_in{in.size() / num_channels};
s16* const out{reinterpret_cast<s16*>(buffer)}; s16* const out{reinterpret_cast<s16*>(buffer)};
const size_t out_frames = impl->time_stretch.Process(in.data(), num_in, out, num_frames); const std::size_t out_frames =
impl->time_stretch.Process(in.data(), num_in, out, num_frames);
samples_written = out_frames * num_channels; samples_written = out_frames * num_channels;
if (impl->should_flush) { if (impl->should_flush) {
@ -184,7 +185,7 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const
} }
// Fill the rest of the frames with last_frame // Fill the rest of the frames with last_frame
for (size_t i = samples_written; i < samples_to_write; i += num_channels) { for (std::size_t i = samples_written; i < samples_to_write; i += num_channels) {
std::memcpy(buffer + i * sizeof(s16), &impl->last_frame[0], num_channels * sizeof(s16)); std::memcpy(buffer + i * sizeof(s16), &impl->last_frame[0], num_channels * sizeof(s16));
} }
@ -197,7 +198,7 @@ std::vector<std::string> ListCubebSinkDevices() {
std::vector<std::string> device_list; std::vector<std::string> device_list;
cubeb* ctx; cubeb* ctx;
if (cubeb_init(&ctx, "Citra Device Enumerator", nullptr) != CUBEB_OK) { if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
return {}; return {};
} }
@ -206,7 +207,7 @@ std::vector<std::string> ListCubebSinkDevices() {
if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) { if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) {
LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported"); LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
} else { } else {
for (size_t i = 0; i < collection.count; i++) { for (std::size_t i = 0; i < collection.count; i++) {
const cubeb_device_info& device = collection.device[i]; const cubeb_device_info& device = collection.device[i];
if (device.friendly_name) { if (device.friendly_name) {
device_list.emplace_back(device.friendly_name); device_list.emplace_back(device.friendly_name);

View file

@ -22,7 +22,7 @@ private:
struct NullSinkStreamImpl final : SinkStream { struct NullSinkStreamImpl final : SinkStream {
void EnqueueSamples(u32 /*num_channels*/, const std::vector<s16>& /*samples*/) override {} void EnqueueSamples(u32 /*num_channels*/, const std::vector<s16>& /*samples*/) override {}
size_t SamplesInQueue(u32 /*num_channels*/) const override { std::size_t SamplesInQueue(u32 /*num_channels*/) const override {
return 0; return 0;
} }

View file

@ -7,6 +7,7 @@
#include "audio_core/sink.h" #include "audio_core/sink.h"
#include "audio_core/sink_details.h" #include "audio_core/sink_details.h"
#include "audio_core/sink_stream.h"
#include "audio_core/stream.h" #include "audio_core/stream.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
@ -17,7 +18,7 @@
namespace AudioCore { namespace AudioCore {
constexpr size_t MaxAudioBufferCount{32}; constexpr std::size_t MaxAudioBufferCount{32};
u32 Stream::GetNumChannels() const { u32 Stream::GetNumChannels() const {
switch (format) { switch (format) {
@ -52,7 +53,7 @@ void Stream::Stop() {
} }
s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const { s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
const size_t num_samples{buffer.GetSamples().size() / GetNumChannels()}; const std::size_t num_samples{buffer.GetSamples().size() / GetNumChannels()};
return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate); return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
} }
@ -122,9 +123,9 @@ bool Stream::ContainsBuffer(Buffer::Tag tag) const {
return {}; return {};
} }
std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers(size_t max_count) { std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers(std::size_t max_count) {
std::vector<Buffer::Tag> tags; std::vector<Buffer::Tag> tags;
for (size_t count = 0; count < max_count && !released_buffers.empty(); ++count) { for (std::size_t count = 0; count < max_count && !released_buffers.empty(); ++count) {
tags.push_back(released_buffers.front()->GetTag()); tags.push_back(released_buffers.front()->GetTag());
released_buffers.pop(); released_buffers.pop();
} }

View file

@ -11,13 +11,16 @@
#include <queue> #include <queue>
#include "audio_core/buffer.h" #include "audio_core/buffer.h"
#include "audio_core/sink_stream.h"
#include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "core/core_timing.h"
namespace CoreTiming {
struct EventType;
}
namespace AudioCore { namespace AudioCore {
class SinkStream;
/** /**
* Represents an audio stream, which is a sequence of queued buffers, to be outputed by AudioOut * Represents an audio stream, which is a sequence of queued buffers, to be outputed by AudioOut
*/ */
@ -49,7 +52,7 @@ public:
bool ContainsBuffer(Buffer::Tag tag) const; bool ContainsBuffer(Buffer::Tag tag) const;
/// Returns a vector of recently released buffers specified by tag /// Returns a vector of recently released buffers specified by tag
std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(size_t max_count); std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(std::size_t max_count);
/// Returns true if the stream is currently playing /// Returns true if the stream is currently playing
bool IsPlaying() const { bool IsPlaying() const {
@ -57,7 +60,7 @@ public:
} }
/// Returns the number of queued buffers /// Returns the number of queued buffers
size_t GetQueueSize() const { std::size_t GetQueueSize() const {
return queued_buffers.size(); return queued_buffers.size();
} }

View file

@ -26,7 +26,8 @@ void TimeStretcher::Flush() {
m_sound_touch.flush(); m_sound_touch.flush();
} }
size_t TimeStretcher::Process(const s16* in, size_t num_in, s16* out, size_t num_out) { std::size_t TimeStretcher::Process(const s16* in, std::size_t num_in, s16* out,
std::size_t num_out) {
const double time_delta = static_cast<double>(num_out) / m_sample_rate; // seconds const double time_delta = static_cast<double>(num_out) / m_sample_rate; // seconds
// We were given actual_samples number of samples, and num_samples were requested from us. // We were given actual_samples number of samples, and num_samples were requested from us.
@ -61,8 +62,8 @@ size_t TimeStretcher::Process(const s16* in, size_t num_in, s16* out, size_t num
LOG_DEBUG(Audio, "{:5}/{:5} ratio:{:0.6f} backlog:{:0.6f}", num_in, num_out, m_stretch_ratio, LOG_DEBUG(Audio, "{:5}/{:5} ratio:{:0.6f} backlog:{:0.6f}", num_in, num_out, m_stretch_ratio,
backlog_fullness); backlog_fullness);
m_sound_touch.putSamples(in, num_in); m_sound_touch.putSamples(in, static_cast<u32>(num_in));
return m_sound_touch.receiveSamples(out, num_out); return m_sound_touch.receiveSamples(out, static_cast<u32>(num_out));
} }
} // namespace AudioCore } // namespace AudioCore

View file

@ -4,7 +4,6 @@
#pragma once #pragma once
#include <array>
#include <cstddef> #include <cstddef>
#include <SoundTouch.h> #include <SoundTouch.h>
#include "common/common_types.h" #include "common/common_types.h"
@ -20,7 +19,7 @@ public:
/// @param out Output sample buffer /// @param out Output sample buffer
/// @param num_out Desired number of output frames in `out` /// @param num_out Desired number of output frames in `out`
/// @returns Actual number of frames written to `out` /// @returns Actual number of frames written to `out`
size_t Process(const s16* in, size_t num_in, s16* out, size_t num_out); std::size_t Process(const s16* in, std::size_t num_in, s16* out, std::size_t num_out);
void Clear(); void Clear();

View file

@ -8,13 +8,13 @@
namespace Common { namespace Common {
template <typename T> template <typename T>
constexpr T AlignUp(T value, size_t size) { constexpr T AlignUp(T value, std::size_t size) {
static_assert(std::is_unsigned_v<T>, "T must be an unsigned value."); static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
return static_cast<T>(value + (size - value % size) % size); return static_cast<T>(value + (size - value % size) % size);
} }
template <typename T> template <typename T>
constexpr T AlignDown(T value, size_t size) { constexpr T AlignDown(T value, std::size_t size) {
static_assert(std::is_unsigned_v<T>, "T must be an unsigned value."); static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
return static_cast<T>(value - value % size); return static_cast<T>(value - value % size);
} }

View file

@ -129,8 +129,8 @@ private:
public: public:
/// Constants to allow limited introspection of fields if needed /// Constants to allow limited introspection of fields if needed
static constexpr size_t position = Position; static constexpr std::size_t position = Position;
static constexpr size_t bits = Bits; static constexpr std::size_t bits = Bits;
static constexpr StorageType mask = (((StorageTypeU)~0) >> (8 * sizeof(T) - bits)) << position; static constexpr StorageType mask = (((StorageTypeU)~0) >> (8 * sizeof(T) - bits)) << position;
/** /**

View file

@ -170,14 +170,14 @@ public:
m_val |= (IntTy)1 << bit; m_val |= (IntTy)1 << bit;
} }
static BitSet AllTrue(size_t count) { static BitSet AllTrue(std::size_t count) {
return BitSet(count == sizeof(IntTy) * 8 ? ~(IntTy)0 : (((IntTy)1 << count) - 1)); return BitSet(count == sizeof(IntTy) * 8 ? ~(IntTy)0 : (((IntTy)1 << count) - 1));
} }
Ref operator[](size_t bit) { Ref operator[](std::size_t bit) {
return Ref(this, (IntTy)1 << bit); return Ref(this, (IntTy)1 << bit);
} }
const Ref operator[](size_t bit) const { const Ref operator[](std::size_t bit) const {
return (*const_cast<BitSet*>(this))[bit]; return (*const_cast<BitSet*>(this))[bit];
} }
bool operator==(BitSet other) const { bool operator==(BitSet other) const {

View file

@ -114,7 +114,7 @@ static uint64 HashLen16(uint64 u, uint64 v, uint64 mul) {
return b; return b;
} }
static uint64 HashLen0to16(const char* s, size_t len) { static uint64 HashLen0to16(const char* s, std::size_t len) {
if (len >= 8) { if (len >= 8) {
uint64 mul = k2 + len * 2; uint64 mul = k2 + len * 2;
uint64 a = Fetch64(s) + k2; uint64 a = Fetch64(s) + k2;
@ -141,7 +141,7 @@ static uint64 HashLen0to16(const char* s, size_t len) {
// This probably works well for 16-byte strings as well, but it may be overkill // This probably works well for 16-byte strings as well, but it may be overkill
// in that case. // in that case.
static uint64 HashLen17to32(const char* s, size_t len) { static uint64 HashLen17to32(const char* s, std::size_t len) {
uint64 mul = k2 + len * 2; uint64 mul = k2 + len * 2;
uint64 a = Fetch64(s) * k1; uint64 a = Fetch64(s) * k1;
uint64 b = Fetch64(s + 8); uint64 b = Fetch64(s + 8);
@ -170,7 +170,7 @@ static pair<uint64, uint64> WeakHashLen32WithSeeds(const char* s, uint64 a, uint
} }
// Return an 8-byte hash for 33 to 64 bytes. // Return an 8-byte hash for 33 to 64 bytes.
static uint64 HashLen33to64(const char* s, size_t len) { static uint64 HashLen33to64(const char* s, std::size_t len) {
uint64 mul = k2 + len * 2; uint64 mul = k2 + len * 2;
uint64 a = Fetch64(s) * k2; uint64 a = Fetch64(s) * k2;
uint64 b = Fetch64(s + 8); uint64 b = Fetch64(s + 8);
@ -191,7 +191,7 @@ static uint64 HashLen33to64(const char* s, size_t len) {
return b + x; return b + x;
} }
uint64 CityHash64(const char* s, size_t len) { uint64 CityHash64(const char* s, std::size_t len) {
if (len <= 32) { if (len <= 32) {
if (len <= 16) { if (len <= 16) {
return HashLen0to16(s, len); return HashLen0to16(s, len);
@ -212,7 +212,7 @@ uint64 CityHash64(const char* s, size_t len) {
x = x * k1 + Fetch64(s); x = x * k1 + Fetch64(s);
// Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
len = (len - 1) & ~static_cast<size_t>(63); len = (len - 1) & ~static_cast<std::size_t>(63);
do { do {
x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1; x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1; y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
@ -229,17 +229,17 @@ uint64 CityHash64(const char* s, size_t len) {
HashLen16(v.second, w.second) + x); HashLen16(v.second, w.second) + x);
} }
uint64 CityHash64WithSeed(const char* s, size_t len, uint64 seed) { uint64 CityHash64WithSeed(const char* s, std::size_t len, uint64 seed) {
return CityHash64WithSeeds(s, len, k2, seed); return CityHash64WithSeeds(s, len, k2, seed);
} }
uint64 CityHash64WithSeeds(const char* s, size_t len, uint64 seed0, uint64 seed1) { uint64 CityHash64WithSeeds(const char* s, std::size_t len, uint64 seed0, uint64 seed1) {
return HashLen16(CityHash64(s, len) - seed0, seed1); return HashLen16(CityHash64(s, len) - seed0, seed1);
} }
// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings // A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
// of any length representable in signed long. Based on City and Murmur. // of any length representable in signed long. Based on City and Murmur.
static uint128 CityMurmur(const char* s, size_t len, uint128 seed) { static uint128 CityMurmur(const char* s, std::size_t len, uint128 seed) {
uint64 a = Uint128Low64(seed); uint64 a = Uint128Low64(seed);
uint64 b = Uint128High64(seed); uint64 b = Uint128High64(seed);
uint64 c = 0; uint64 c = 0;
@ -269,7 +269,7 @@ static uint128 CityMurmur(const char* s, size_t len, uint128 seed) {
return uint128(a ^ b, HashLen16(b, a)); return uint128(a ^ b, HashLen16(b, a));
} }
uint128 CityHash128WithSeed(const char* s, size_t len, uint128 seed) { uint128 CityHash128WithSeed(const char* s, std::size_t len, uint128 seed) {
if (len < 128) { if (len < 128) {
return CityMurmur(s, len, seed); return CityMurmur(s, len, seed);
} }
@ -313,7 +313,7 @@ uint128 CityHash128WithSeed(const char* s, size_t len, uint128 seed) {
w.first *= 9; w.first *= 9;
v.first *= k0; v.first *= k0;
// If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s. // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
for (size_t tail_done = 0; tail_done < len;) { for (std::size_t tail_done = 0; tail_done < len;) {
tail_done += 32; tail_done += 32;
y = Rotate(x + y, 42) * k0 + v.second; y = Rotate(x + y, 42) * k0 + v.second;
w.first += Fetch64(s + len - tail_done + 16); w.first += Fetch64(s + len - tail_done + 16);
@ -331,7 +331,7 @@ uint128 CityHash128WithSeed(const char* s, size_t len, uint128 seed) {
return uint128(HashLen16(x + v.second, w.second) + y, HashLen16(x + w.second, y + v.second)); return uint128(HashLen16(x + v.second, w.second) + y, HashLen16(x + w.second, y + v.second));
} }
uint128 CityHash128(const char* s, size_t len) { uint128 CityHash128(const char* s, std::size_t len) {
return len >= 16 return len >= 16
? CityHash128WithSeed(s + 16, len - 16, uint128(Fetch64(s), Fetch64(s + 8) + k0)) ? CityHash128WithSeed(s + 16, len - 16, uint128(Fetch64(s), Fetch64(s + 8) + k0))
: CityHash128WithSeed(s, len, uint128(k0, k1)); : CityHash128WithSeed(s, len, uint128(k0, k1));

View file

@ -63,7 +63,7 @@
#include <utility> #include <utility>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> // for size_t. #include <stdlib.h> // for std::size_t.
namespace Common { namespace Common {
@ -77,22 +77,22 @@ inline uint64_t Uint128High64(const uint128& x) {
} }
// Hash function for a byte array. // Hash function for a byte array.
uint64_t CityHash64(const char* buf, size_t len); uint64_t CityHash64(const char* buf, std::size_t len);
// Hash function for a byte array. For convenience, a 64-bit seed is also // Hash function for a byte array. For convenience, a 64-bit seed is also
// hashed into the result. // hashed into the result.
uint64_t CityHash64WithSeed(const char* buf, size_t len, uint64_t seed); uint64_t CityHash64WithSeed(const char* buf, std::size_t len, uint64_t seed);
// Hash function for a byte array. For convenience, two seeds are also // Hash function for a byte array. For convenience, two seeds are also
// hashed into the result. // hashed into the result.
uint64_t CityHash64WithSeeds(const char* buf, size_t len, uint64_t seed0, uint64_t seed1); uint64_t CityHash64WithSeeds(const char* buf, std::size_t len, uint64_t seed0, uint64_t seed1);
// Hash function for a byte array. // Hash function for a byte array.
uint128 CityHash128(const char* s, size_t len); uint128 CityHash128(const char* s, std::size_t len);
// Hash function for a byte array. For convenience, a 128-bit seed is also // Hash function for a byte array. For convenience, a 128-bit seed is also
// hashed into the result. // hashed into the result.
uint128 CityHash128WithSeed(const char* s, size_t len, uint128 seed); uint128 CityHash128WithSeed(const char* s, std::size_t len, uint128 seed);
// Hash 128 input bits down to 64 bits of output. // Hash 128 input bits down to 64 bits of output.
// This is intended to be a reasonably good hash function. // This is intended to be a reasonably good hash function.

View file

@ -76,7 +76,7 @@ namespace FileUtil {
// Modifies argument. // Modifies argument.
static void StripTailDirSlashes(std::string& fname) { static void StripTailDirSlashes(std::string& fname) {
if (fname.length() > 1) { if (fname.length() > 1) {
size_t i = fname.length(); std::size_t i = fname.length();
while (i > 0 && fname[i - 1] == DIR_SEP_CHR) while (i > 0 && fname[i - 1] == DIR_SEP_CHR)
--i; --i;
fname.resize(i); fname.resize(i);
@ -201,7 +201,7 @@ bool CreateFullPath(const std::string& fullPath) {
return true; return true;
} }
size_t position = 0; std::size_t position = 0;
while (true) { while (true) {
// Find next sub path // Find next sub path
position = fullPath.find(DIR_SEP_CHR, position); position = fullPath.find(DIR_SEP_CHR, position);
@ -299,7 +299,7 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
std::array<char, 1024> buffer; std::array<char, 1024> buffer;
while (!feof(input.get())) { while (!feof(input.get())) {
// read input // read input
size_t rnum = fread(buffer.data(), sizeof(char), buffer.size(), input.get()); std::size_t rnum = fread(buffer.data(), sizeof(char), buffer.size(), input.get());
if (rnum != buffer.size()) { if (rnum != buffer.size()) {
if (ferror(input.get()) != 0) { if (ferror(input.get()) != 0) {
LOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}", LOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}",
@ -309,7 +309,7 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
} }
// write output // write output
size_t wnum = fwrite(buffer.data(), sizeof(char), rnum, output.get()); std::size_t wnum = fwrite(buffer.data(), sizeof(char), rnum, output.get());
if (wnum != rnum) { if (wnum != rnum) {
LOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename, LOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename,
destFilename, GetLastErrorMsg()); destFilename, GetLastErrorMsg());
@ -756,11 +756,11 @@ std::string GetNANDRegistrationDir(bool system) {
return GetUserPath(UserPath::NANDDir) + "user/Contents/registered/"; return GetUserPath(UserPath::NANDDir) + "user/Contents/registered/";
} }
size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) { std::size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) {
return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size());
} }
size_t ReadFileToString(bool text_file, const char* filename, std::string& str) { std::size_t ReadFileToString(bool text_file, const char* filename, std::string& str) {
IOFile file(filename, text_file ? "r" : "rb"); IOFile file(filename, text_file ? "r" : "rb");
if (!file.IsOpen()) if (!file.IsOpen())
@ -829,7 +829,7 @@ std::vector<std::string> SplitPathComponents(std::string_view filename) {
std::string_view GetParentPath(std::string_view path) { std::string_view GetParentPath(std::string_view path) {
const auto name_bck_index = path.rfind('\\'); const auto name_bck_index = path.rfind('\\');
const auto name_fwd_index = path.rfind('/'); const auto name_fwd_index = path.rfind('/');
size_t name_index; std::size_t name_index;
if (name_bck_index == std::string_view::npos || name_fwd_index == std::string_view::npos) { if (name_bck_index == std::string_view::npos || name_fwd_index == std::string_view::npos) {
name_index = std::min(name_bck_index, name_fwd_index); name_index = std::min(name_bck_index, name_fwd_index);
@ -868,7 +868,7 @@ std::string_view GetFilename(std::string_view path) {
} }
std::string_view GetExtensionFromFilename(std::string_view name) { std::string_view GetExtensionFromFilename(std::string_view name) {
const size_t index = name.rfind('.'); const std::size_t index = name.rfind('.');
if (index == std::string_view::npos) { if (index == std::string_view::npos) {
return {}; return {};

View file

@ -143,8 +143,9 @@ const std::string& GetExeDirectory();
std::string AppDataRoamingDirectory(); std::string AppDataRoamingDirectory();
#endif #endif
size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename); std::size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename);
size_t ReadFileToString(bool text_file, const char* filename, std::string& str);
std::size_t ReadFileToString(bool text_file, const char* filename, std::string& str);
/** /**
* Splits the filename into 8.3 format * Splits the filename into 8.3 format
@ -177,10 +178,10 @@ std::string_view RemoveTrailingSlash(std::string_view path);
// Creates a new vector containing indices [first, last) from the original. // Creates a new vector containing indices [first, last) from the original.
template <typename T> template <typename T>
std::vector<T> SliceVector(const std::vector<T>& vector, size_t first, size_t last) { std::vector<T> SliceVector(const std::vector<T>& vector, std::size_t first, std::size_t last) {
if (first >= last) if (first >= last)
return {}; return {};
last = std::min<size_t>(last, vector.size()); last = std::min<std::size_t>(last, vector.size());
return std::vector<T>(vector.begin() + first, vector.begin() + first + last); return std::vector<T>(vector.begin() + first, vector.begin() + first + last);
} }
@ -213,47 +214,47 @@ public:
bool Close(); bool Close();
template <typename T> template <typename T>
size_t ReadArray(T* data, size_t length) const { std::size_t ReadArray(T* data, std::size_t length) const {
static_assert(std::is_trivially_copyable_v<T>, static_assert(std::is_trivially_copyable_v<T>,
"Given array does not consist of trivially copyable objects"); "Given array does not consist of trivially copyable objects");
if (!IsOpen()) { if (!IsOpen()) {
return std::numeric_limits<size_t>::max(); return std::numeric_limits<std::size_t>::max();
} }
return std::fread(data, sizeof(T), length, m_file); return std::fread(data, sizeof(T), length, m_file);
} }
template <typename T> template <typename T>
size_t WriteArray(const T* data, size_t length) { std::size_t WriteArray(const T* data, std::size_t length) {
static_assert(std::is_trivially_copyable_v<T>, static_assert(std::is_trivially_copyable_v<T>,
"Given array does not consist of trivially copyable objects"); "Given array does not consist of trivially copyable objects");
if (!IsOpen()) { if (!IsOpen()) {
return std::numeric_limits<size_t>::max(); return std::numeric_limits<std::size_t>::max();
} }
return std::fwrite(data, sizeof(T), length, m_file); return std::fwrite(data, sizeof(T), length, m_file);
} }
template <typename T> template <typename T>
size_t ReadBytes(T* data, size_t length) const { std::size_t ReadBytes(T* data, std::size_t length) const {
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable"); static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");
return ReadArray(reinterpret_cast<char*>(data), length); return ReadArray(reinterpret_cast<char*>(data), length);
} }
template <typename T> template <typename T>
size_t WriteBytes(const T* data, size_t length) { std::size_t WriteBytes(const T* data, std::size_t length) {
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable"); static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");
return WriteArray(reinterpret_cast<const char*>(data), length); return WriteArray(reinterpret_cast<const char*>(data), length);
} }
template <typename T> template <typename T>
size_t WriteObject(const T& object) { std::size_t WriteObject(const T& object) {
static_assert(!std::is_pointer_v<T>, "WriteObject arguments must not be a pointer"); static_assert(!std::is_pointer_v<T>, "WriteObject arguments must not be a pointer");
return WriteArray(&object, 1); return WriteArray(&object, 1);
} }
size_t WriteString(const std::string& str) { std::size_t WriteString(const std::string& str) {
return WriteArray(str.c_str(), str.length()); return WriteArray(str.c_str(), str.length());
} }

View file

@ -17,7 +17,7 @@ namespace Common {
* @param len Length of data (in bytes) to compute hash over * @param len Length of data (in bytes) to compute hash over
* @returns 64-bit hash value that was computed over the data block * @returns 64-bit hash value that was computed over the data block
*/ */
static inline u64 ComputeHash64(const void* data, size_t len) { static inline u64 ComputeHash64(const void* data, std::size_t len) {
return CityHash64(static_cast<const char*>(data), len); return CityHash64(static_cast<const char*>(data), len);
} }
@ -63,7 +63,7 @@ struct HashableStruct {
return !(*this == o); return !(*this == o);
}; };
size_t Hash() const { std::size_t Hash() const {
return Common::ComputeStructHash64(state); return Common::ComputeStructHash64(state);
} }
}; };

View file

@ -18,7 +18,7 @@ u8 ToHexNibble(char c1) {
return 0; return 0;
} }
std::array<u8, 16> operator""_array16(const char* str, size_t len) { std::array<u8, 16> operator""_array16(const char* str, std::size_t len) {
if (len != 32) { if (len != 32) {
LOG_ERROR(Common, LOG_ERROR(Common,
"Attempting to parse string to array that is not of correct size (expected=32, " "Attempting to parse string to array that is not of correct size (expected=32, "
@ -29,7 +29,7 @@ std::array<u8, 16> operator""_array16(const char* str, size_t len) {
return HexStringToArray<16>(str); return HexStringToArray<16>(str);
} }
std::array<u8, 32> operator""_array32(const char* str, size_t len) { std::array<u8, 32> operator""_array32(const char* str, std::size_t len) {
if (len != 64) { if (len != 64) {
LOG_ERROR(Common, LOG_ERROR(Common,
"Attempting to parse string to array that is not of correct size (expected=64, " "Attempting to parse string to array that is not of correct size (expected=64, "

View file

@ -14,20 +14,20 @@ namespace Common {
u8 ToHexNibble(char c1); u8 ToHexNibble(char c1);
template <size_t Size, bool le = false> template <std::size_t Size, bool le = false>
std::array<u8, Size> HexStringToArray(std::string_view str) { std::array<u8, Size> HexStringToArray(std::string_view str) {
std::array<u8, Size> out{}; std::array<u8, Size> out{};
if constexpr (le) { if constexpr (le) {
for (size_t i = 2 * Size - 2; i <= 2 * Size; i -= 2) for (std::size_t i = 2 * Size - 2; i <= 2 * Size; i -= 2)
out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]); out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
} else { } else {
for (size_t i = 0; i < 2 * Size; i += 2) for (std::size_t i = 0; i < 2 * Size; i += 2)
out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]); out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]);
} }
return out; return out;
} }
template <size_t Size> template <std::size_t Size>
std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) { std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) {
std::string out; std::string out;
for (u8 c : array) for (u8 c : array)
@ -35,7 +35,7 @@ std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) {
return out; return out;
} }
std::array<u8, 0x10> operator"" _array16(const char* str, size_t len); std::array<u8, 0x10> operator"" _array16(const char* str, std::size_t len);
std::array<u8, 0x20> operator"" _array32(const char* str, size_t len); std::array<u8, 0x20> operator"" _array32(const char* str, std::size_t len);
} // namespace Common } // namespace Common

View file

@ -135,7 +135,7 @@ FileBackend::FileBackend(const std::string& filename)
void FileBackend::Write(const Entry& entry) { void FileBackend::Write(const Entry& entry) {
// prevent logs from going over the maximum size (in case its spamming and the user doesn't // prevent logs from going over the maximum size (in case its spamming and the user doesn't
// know) // know)
constexpr size_t MAX_BYTES_WRITTEN = 50 * 1024L * 1024L; constexpr std::size_t MAX_BYTES_WRITTEN = 50 * 1024L * 1024L;
if (!file.IsOpen() || bytes_written > MAX_BYTES_WRITTEN) { if (!file.IsOpen() || bytes_written > MAX_BYTES_WRITTEN) {
return; return;
} }

View file

@ -100,7 +100,7 @@ public:
private: private:
FileUtil::IOFile file; FileUtil::IOFile file;
size_t bytes_written; std::size_t bytes_written;
}; };
void AddBackend(std::unique_ptr<Backend> backend); void AddBackend(std::unique_ptr<Backend> backend);

View file

@ -71,7 +71,7 @@ void Filter::ResetAll(Level level) {
} }
void Filter::SetClassLevel(Class log_class, Level level) { void Filter::SetClassLevel(Class log_class, Level level) {
class_levels[static_cast<size_t>(log_class)] = level; class_levels[static_cast<std::size_t>(log_class)] = level;
} }
void Filter::ParseFilterString(std::string_view filter_view) { void Filter::ParseFilterString(std::string_view filter_view) {
@ -93,7 +93,8 @@ void Filter::ParseFilterString(std::string_view filter_view) {
} }
bool Filter::CheckMessage(Class log_class, Level level) const { bool Filter::CheckMessage(Class log_class, Level level) const {
return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]); return static_cast<u8>(level) >=
static_cast<u8>(class_levels[static_cast<std::size_t>(log_class)]);
} }
bool Filter::IsDebug() const { bool Filter::IsDebug() const {

View file

@ -49,6 +49,6 @@ public:
bool IsDebug() const; bool IsDebug() const;
private: private:
std::array<Level, static_cast<size_t>(Class::Count)> class_levels; std::array<Level, static_cast<std::size_t>(Class::Count)> class_levels;
}; };
} // namespace Log } // namespace Log

View file

@ -25,7 +25,7 @@
// This is purposely not a full wrapper for virtualalloc/mmap, but it // This is purposely not a full wrapper for virtualalloc/mmap, but it
// provides exactly the primitive operations that Dolphin needs. // provides exactly the primitive operations that Dolphin needs.
void* AllocateExecutableMemory(size_t size, bool low) { void* AllocateExecutableMemory(std::size_t size, bool low) {
#if defined(_WIN32) #if defined(_WIN32)
void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else #else
@ -74,7 +74,7 @@ void* AllocateExecutableMemory(size_t size, bool low) {
return ptr; return ptr;
} }
void* AllocateMemoryPages(size_t size) { void* AllocateMemoryPages(std::size_t size) {
#ifdef _WIN32 #ifdef _WIN32
void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE); void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE);
#else #else
@ -90,7 +90,7 @@ void* AllocateMemoryPages(size_t size) {
return ptr; return ptr;
} }
void* AllocateAlignedMemory(size_t size, size_t alignment) { void* AllocateAlignedMemory(std::size_t size, std::size_t alignment) {
#ifdef _WIN32 #ifdef _WIN32
void* ptr = _aligned_malloc(size, alignment); void* ptr = _aligned_malloc(size, alignment);
#else #else
@ -109,7 +109,7 @@ void* AllocateAlignedMemory(size_t size, size_t alignment) {
return ptr; return ptr;
} }
void FreeMemoryPages(void* ptr, size_t size) { void FreeMemoryPages(void* ptr, std::size_t size) {
if (ptr) { if (ptr) {
#ifdef _WIN32 #ifdef _WIN32
if (!VirtualFree(ptr, 0, MEM_RELEASE)) if (!VirtualFree(ptr, 0, MEM_RELEASE))
@ -130,7 +130,7 @@ void FreeAlignedMemory(void* ptr) {
} }
} }
void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) { void WriteProtectMemory(void* ptr, std::size_t size, bool allowExecute) {
#ifdef _WIN32 #ifdef _WIN32
DWORD oldValue; DWORD oldValue;
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue)) if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
@ -140,7 +140,7 @@ void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) {
#endif #endif
} }
void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) { void UnWriteProtectMemory(void* ptr, std::size_t size, bool allowExecute) {
#ifdef _WIN32 #ifdef _WIN32
DWORD oldValue; DWORD oldValue;
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,

View file

@ -7,13 +7,13 @@
#include <cstddef> #include <cstddef>
#include <string> #include <string>
void* AllocateExecutableMemory(size_t size, bool low = true); void* AllocateExecutableMemory(std::size_t size, bool low = true);
void* AllocateMemoryPages(size_t size); void* AllocateMemoryPages(std::size_t size);
void FreeMemoryPages(void* ptr, size_t size); void FreeMemoryPages(void* ptr, std::size_t size);
void* AllocateAlignedMemory(size_t size, size_t alignment); void* AllocateAlignedMemory(std::size_t size, std::size_t alignment);
void FreeAlignedMemory(void* ptr); void FreeAlignedMemory(void* ptr);
void WriteProtectMemory(void* ptr, size_t size, bool executable = false); void WriteProtectMemory(void* ptr, std::size_t size, bool executable = false);
void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute = false); void UnWriteProtectMemory(void* ptr, std::size_t size, bool allowExecute = false);
std::string MemUsage(); std::string MemUsage();
inline int GetPageSize() { inline int GetPageSize() {

View file

@ -16,7 +16,7 @@
// Call directly after the command or use the error num. // Call directly after the command or use the error num.
// This function might change the error code. // This function might change the error code.
std::string GetLastErrorMsg() { std::string GetLastErrorMsg() {
static const size_t buff_size = 255; static const std::size_t buff_size = 255;
char err_str[buff_size]; char err_str[buff_size];
#ifdef _WIN32 #ifdef _WIN32

View file

@ -19,31 +19,31 @@ namespace Common {
/// @tparam T Element type /// @tparam T Element type
/// @tparam capacity Number of slots in ring buffer /// @tparam capacity Number of slots in ring buffer
/// @tparam granularity Slot size in terms of number of elements /// @tparam granularity Slot size in terms of number of elements
template <typename T, size_t capacity, size_t granularity = 1> template <typename T, std::size_t capacity, std::size_t granularity = 1>
class RingBuffer { class RingBuffer {
/// A "slot" is made of `granularity` elements of `T`. /// A "slot" is made of `granularity` elements of `T`.
static constexpr size_t slot_size = granularity * sizeof(T); static constexpr std::size_t slot_size = granularity * sizeof(T);
// T must be safely memcpy-able and have a trivial default constructor. // T must be safely memcpy-able and have a trivial default constructor.
static_assert(std::is_trivial_v<T>); static_assert(std::is_trivial_v<T>);
// Ensure capacity is sensible. // Ensure capacity is sensible.
static_assert(capacity < std::numeric_limits<size_t>::max() / 2 / granularity); static_assert(capacity < std::numeric_limits<std::size_t>::max() / 2 / granularity);
static_assert((capacity & (capacity - 1)) == 0, "capacity must be a power of two"); static_assert((capacity & (capacity - 1)) == 0, "capacity must be a power of two");
// Ensure lock-free. // Ensure lock-free.
static_assert(std::atomic<size_t>::is_always_lock_free); static_assert(std::atomic<std::size_t>::is_always_lock_free);
public: public:
/// Pushes slots into the ring buffer /// Pushes slots into the ring buffer
/// @param new_slots Pointer to the slots to push /// @param new_slots Pointer to the slots to push
/// @param slot_count Number of slots to push /// @param slot_count Number of slots to push
/// @returns The number of slots actually pushed /// @returns The number of slots actually pushed
size_t Push(const void* new_slots, size_t slot_count) { std::size_t Push(const void* new_slots, std::size_t slot_count) {
const size_t write_index = m_write_index.load(); const std::size_t write_index = m_write_index.load();
const size_t slots_free = capacity + m_read_index.load() - write_index; const std::size_t slots_free = capacity + m_read_index.load() - write_index;
const size_t push_count = std::min(slot_count, slots_free); const std::size_t push_count = std::min(slot_count, slots_free);
const size_t pos = write_index % capacity; const std::size_t pos = write_index % capacity;
const size_t first_copy = std::min(capacity - pos, push_count); const std::size_t first_copy = std::min(capacity - pos, push_count);
const size_t second_copy = push_count - first_copy; const std::size_t second_copy = push_count - first_copy;
const char* in = static_cast<const char*>(new_slots); const char* in = static_cast<const char*>(new_slots);
std::memcpy(m_data.data() + pos * granularity, in, first_copy * slot_size); std::memcpy(m_data.data() + pos * granularity, in, first_copy * slot_size);
@ -55,7 +55,7 @@ public:
return push_count; return push_count;
} }
size_t Push(const std::vector<T>& input) { std::size_t Push(const std::vector<T>& input) {
return Push(input.data(), input.size()); return Push(input.data(), input.size());
} }
@ -63,14 +63,14 @@ public:
/// @param output Where to store the popped slots /// @param output Where to store the popped slots
/// @param max_slots Maximum number of slots to pop /// @param max_slots Maximum number of slots to pop
/// @returns The number of slots actually popped /// @returns The number of slots actually popped
size_t Pop(void* output, size_t max_slots = ~size_t(0)) { std::size_t Pop(void* output, std::size_t max_slots = ~std::size_t(0)) {
const size_t read_index = m_read_index.load(); const std::size_t read_index = m_read_index.load();
const size_t slots_filled = m_write_index.load() - read_index; const std::size_t slots_filled = m_write_index.load() - read_index;
const size_t pop_count = std::min(slots_filled, max_slots); const std::size_t pop_count = std::min(slots_filled, max_slots);
const size_t pos = read_index % capacity; const std::size_t pos = read_index % capacity;
const size_t first_copy = std::min(capacity - pos, pop_count); const std::size_t first_copy = std::min(capacity - pos, pop_count);
const size_t second_copy = pop_count - first_copy; const std::size_t second_copy = pop_count - first_copy;
char* out = static_cast<char*>(output); char* out = static_cast<char*>(output);
std::memcpy(out, m_data.data() + pos * granularity, first_copy * slot_size); std::memcpy(out, m_data.data() + pos * granularity, first_copy * slot_size);
@ -82,28 +82,28 @@ public:
return pop_count; return pop_count;
} }
std::vector<T> Pop(size_t max_slots = ~size_t(0)) { std::vector<T> Pop(std::size_t max_slots = ~std::size_t(0)) {
std::vector<T> out(std::min(max_slots, capacity) * granularity); std::vector<T> out(std::min(max_slots, capacity) * granularity);
const size_t count = Pop(out.data(), out.size() / granularity); const std::size_t count = Pop(out.data(), out.size() / granularity);
out.resize(count * granularity); out.resize(count * granularity);
return out; return out;
} }
/// @returns Number of slots used /// @returns Number of slots used
size_t Size() const { std::size_t Size() const {
return m_write_index.load() - m_read_index.load(); return m_write_index.load() - m_read_index.load();
} }
/// @returns Maximum size of ring buffer /// @returns Maximum size of ring buffer
constexpr size_t Capacity() const { constexpr std::size_t Capacity() const {
return capacity; return capacity;
} }
private: private:
// It is important to align the below variables for performance reasons: // It is important to align the below variables for performance reasons:
// Having them on the same cache-line would result in false-sharing between them. // Having them on the same cache-line would result in false-sharing between them.
alignas(128) std::atomic<size_t> m_read_index{0}; alignas(128) std::atomic<std::size_t> m_read_index{0};
alignas(128) std::atomic<size_t> m_write_index{0}; alignas(128) std::atomic<std::size_t> m_write_index{0};
std::array<T, granularity * capacity> m_data; std::array<T, granularity * capacity> m_data;
}; };

View file

@ -37,7 +37,7 @@ std::string ToUpper(std::string str) {
} }
// For Debugging. Read out an u8 array. // For Debugging. Read out an u8 array.
std::string ArrayToString(const u8* data, size_t size, int line_len, bool spaces) { std::string ArrayToString(const u8* data, std::size_t size, int line_len, bool spaces) {
std::ostringstream oss; std::ostringstream oss;
oss << std::setfill('0') << std::hex; oss << std::setfill('0') << std::hex;
@ -60,7 +60,7 @@ std::string StringFromBuffer(const std::vector<u8>& data) {
// Turns " hej " into "hej". Also handles tabs. // Turns " hej " into "hej". Also handles tabs.
std::string StripSpaces(const std::string& str) { std::string StripSpaces(const std::string& str) {
const size_t s = str.find_first_not_of(" \t\r\n"); const std::size_t s = str.find_first_not_of(" \t\r\n");
if (str.npos != s) if (str.npos != s)
return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1);
@ -121,7 +121,7 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
if (full_path.empty()) if (full_path.empty())
return false; return false;
size_t dir_end = full_path.find_last_of("/" std::size_t dir_end = full_path.find_last_of("/"
// windows needs the : included for something like just "C:" to be considered a directory // windows needs the : included for something like just "C:" to be considered a directory
#ifdef _WIN32 #ifdef _WIN32
"\\:" "\\:"
@ -132,7 +132,7 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
else else
dir_end += 1; dir_end += 1;
size_t fname_end = full_path.rfind('.'); std::size_t fname_end = full_path.rfind('.');
if (fname_end < dir_end || std::string::npos == fname_end) if (fname_end < dir_end || std::string::npos == fname_end)
fname_end = full_path.size(); fname_end = full_path.size();
@ -172,7 +172,7 @@ void SplitString(const std::string& str, const char delim, std::vector<std::stri
} }
std::string TabsToSpaces(int tab_size, std::string in) { std::string TabsToSpaces(int tab_size, std::string in) {
size_t i = 0; std::size_t i = 0;
while ((i = in.find('\t')) != std::string::npos) { while ((i = in.find('\t')) != std::string::npos) {
in.replace(i, 1, tab_size, ' '); in.replace(i, 1, tab_size, ' ');
@ -182,7 +182,7 @@ std::string TabsToSpaces(int tab_size, std::string in) {
} }
std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) { std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) {
size_t pos = 0; std::size_t pos = 0;
if (src == dest) if (src == dest)
return result; return result;
@ -280,22 +280,22 @@ static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>&
return {}; return {};
} }
const size_t in_bytes = sizeof(T) * input.size(); const std::size_t in_bytes = sizeof(T) * input.size();
// Multiply by 4, which is the max number of bytes to encode a codepoint // Multiply by 4, which is the max number of bytes to encode a codepoint
const size_t out_buffer_size = 4 * in_bytes; const std::size_t out_buffer_size = 4 * in_bytes;
std::string out_buffer(out_buffer_size, '\0'); std::string out_buffer(out_buffer_size, '\0');
auto src_buffer = &input[0]; auto src_buffer = &input[0];
size_t src_bytes = in_bytes; std::size_t src_bytes = in_bytes;
auto dst_buffer = &out_buffer[0]; auto dst_buffer = &out_buffer[0];
size_t dst_bytes = out_buffer.size(); std::size_t dst_bytes = out_buffer.size();
while (0 != src_bytes) { while (0 != src_bytes) {
size_t const iconv_result = std::size_t const iconv_result =
iconv(conv_desc, (char**)(&src_buffer), &src_bytes, &dst_buffer, &dst_bytes); iconv(conv_desc, (char**)(&src_buffer), &src_bytes, &dst_buffer, &dst_bytes);
if (static_cast<size_t>(-1) == iconv_result) { if (static_cast<std::size_t>(-1) == iconv_result) {
if (EILSEQ == errno || EINVAL == errno) { if (EILSEQ == errno || EINVAL == errno) {
// Try to skip the bad character // Try to skip the bad character
if (0 != src_bytes) { if (0 != src_bytes) {
@ -326,22 +326,22 @@ std::u16string UTF8ToUTF16(const std::string& input) {
return {}; return {};
} }
const size_t in_bytes = sizeof(char) * input.size(); const std::size_t in_bytes = sizeof(char) * input.size();
// Multiply by 4, which is the max number of bytes to encode a codepoint // Multiply by 4, which is the max number of bytes to encode a codepoint
const size_t out_buffer_size = 4 * sizeof(char16_t) * in_bytes; const std::size_t out_buffer_size = 4 * sizeof(char16_t) * in_bytes;
std::u16string out_buffer(out_buffer_size, char16_t{}); std::u16string out_buffer(out_buffer_size, char16_t{});
char* src_buffer = const_cast<char*>(&input[0]); char* src_buffer = const_cast<char*>(&input[0]);
size_t src_bytes = in_bytes; std::size_t src_bytes = in_bytes;
char* dst_buffer = (char*)(&out_buffer[0]); char* dst_buffer = (char*)(&out_buffer[0]);
size_t dst_bytes = out_buffer.size(); std::size_t dst_bytes = out_buffer.size();
while (0 != src_bytes) { while (0 != src_bytes) {
size_t const iconv_result = std::size_t const iconv_result =
iconv(conv_desc, &src_buffer, &src_bytes, &dst_buffer, &dst_bytes); iconv(conv_desc, &src_buffer, &src_bytes, &dst_buffer, &dst_bytes);
if (static_cast<size_t>(-1) == iconv_result) { if (static_cast<std::size_t>(-1) == iconv_result) {
if (EILSEQ == errno || EINVAL == errno) { if (EILSEQ == errno || EINVAL == errno) {
// Try to skip the bad character // Try to skip the bad character
if (0 != src_bytes) { if (0 != src_bytes) {
@ -381,8 +381,8 @@ std::string SHIFTJISToUTF8(const std::string& input) {
#endif #endif
std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_len) { std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, std::size_t max_len) {
size_t len = 0; std::size_t len = 0;
while (len < max_len && buffer[len] != '\0') while (len < max_len && buffer[len] != '\0')
++len; ++len;

View file

@ -19,7 +19,7 @@ std::string ToLower(std::string str);
/// Make a string uppercase /// Make a string uppercase
std::string ToUpper(std::string str); std::string ToUpper(std::string str);
std::string ArrayToString(const u8* data, size_t size, int line_len = 20, bool spaces = true); std::string ArrayToString(const u8* data, std::size_t size, int line_len = 20, bool spaces = true);
std::string StringFromBuffer(const std::vector<u8>& data); std::string StringFromBuffer(const std::vector<u8>& data);
@ -118,7 +118,7 @@ bool ComparePartialString(InIt begin, InIt end, const char* other) {
* Creates a std::string from a fixed-size NUL-terminated char buffer. If the buffer isn't * Creates a std::string from a fixed-size NUL-terminated char buffer. If the buffer isn't
* NUL-terminated then the string ends at max_len characters. * NUL-terminated then the string ends at max_len characters.
*/ */
std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_len); std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, std::size_t max_len);
/** /**
* Attempts to trim an arbitrary prefix from `path`, leaving only the part starting at `root`. It's * Attempts to trim an arbitrary prefix from `path`, leaving only the part starting at `root`. It's

View file

@ -60,12 +60,12 @@ private:
class Barrier { class Barrier {
public: public:
explicit Barrier(size_t count_) : count(count_), waiting(0), generation(0) {} explicit Barrier(std::size_t count_) : count(count_), waiting(0), generation(0) {}
/// Blocks until all "count" threads have called Sync() /// Blocks until all "count" threads have called Sync()
void Sync() { void Sync() {
std::unique_lock<std::mutex> lk(mutex); std::unique_lock<std::mutex> lk(mutex);
const size_t current_generation = generation; const std::size_t current_generation = generation;
if (++waiting == count) { if (++waiting == count) {
generation++; generation++;
@ -80,9 +80,9 @@ public:
private: private:
std::condition_variable condvar; std::condition_variable condvar;
std::mutex mutex; std::mutex mutex;
const size_t count; const std::size_t count;
size_t waiting; std::size_t waiting;
size_t generation; // Incremented once each time the barrier is used std::size_t generation; // Incremented once each time the barrier is used
}; };
void SleepCurrentThread(int ms); void SleepCurrentThread(int ms);

View file

@ -97,7 +97,7 @@ const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
Xbyak::util::xmm15, Xbyak::util::xmm15,
}); });
constexpr size_t ABI_SHADOW_SPACE = 0x20; constexpr std::size_t ABI_SHADOW_SPACE = 0x20;
#else #else
@ -147,22 +147,23 @@ const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
Xbyak::util::r15, Xbyak::util::r15,
}); });
constexpr size_t ABI_SHADOW_SPACE = 0; constexpr std::size_t ABI_SHADOW_SPACE = 0;
#endif #endif
inline void ABI_CalculateFrameSize(BitSet32 regs, size_t rsp_alignment, size_t needed_frame_size, inline void ABI_CalculateFrameSize(BitSet32 regs, std::size_t rsp_alignment,
s32* out_subtraction, s32* out_xmm_offset) { std::size_t needed_frame_size, s32* out_subtraction,
s32* out_xmm_offset) {
int count = (regs & ABI_ALL_GPRS).Count(); int count = (regs & ABI_ALL_GPRS).Count();
rsp_alignment -= count * 8; rsp_alignment -= count * 8;
size_t subtraction = 0; std::size_t subtraction = 0;
int xmm_count = (regs & ABI_ALL_XMMS).Count(); int xmm_count = (regs & ABI_ALL_XMMS).Count();
if (xmm_count) { if (xmm_count) {
// If we have any XMMs to save, we must align the stack here. // If we have any XMMs to save, we must align the stack here.
subtraction = rsp_alignment & 0xF; subtraction = rsp_alignment & 0xF;
} }
subtraction += 0x10 * xmm_count; subtraction += 0x10 * xmm_count;
size_t xmm_base_subtraction = subtraction; std::size_t xmm_base_subtraction = subtraction;
subtraction += needed_frame_size; subtraction += needed_frame_size;
subtraction += ABI_SHADOW_SPACE; subtraction += ABI_SHADOW_SPACE;
// Final alignment. // Final alignment.
@ -173,8 +174,9 @@ inline void ABI_CalculateFrameSize(BitSet32 regs, size_t rsp_alignment, size_t n
*out_xmm_offset = (s32)(subtraction - xmm_base_subtraction); *out_xmm_offset = (s32)(subtraction - xmm_base_subtraction);
} }
inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs, inline std::size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs,
size_t rsp_alignment, size_t needed_frame_size = 0) { std::size_t rsp_alignment,
std::size_t needed_frame_size = 0) {
s32 subtraction, xmm_offset; s32 subtraction, xmm_offset;
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset); ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
@ -195,7 +197,8 @@ inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet
} }
inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs, inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs,
size_t rsp_alignment, size_t needed_frame_size = 0) { std::size_t rsp_alignment,
std::size_t needed_frame_size = 0) {
s32 subtraction, xmm_offset; s32 subtraction, xmm_offset;
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset); ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);

View file

@ -34,7 +34,7 @@ inline bool IsWithin2G(const Xbyak::CodeGenerator& code, uintptr_t target) {
template <typename T> template <typename T>
inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) { inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) {
static_assert(std::is_pointer_v<T>, "Argument must be a (function) pointer."); static_assert(std::is_pointer_v<T>, "Argument must be a (function) pointer.");
size_t addr = reinterpret_cast<size_t>(f); std::size_t addr = reinterpret_cast<std::size_t>(f);
if (IsWithin2G(code, addr)) { if (IsWithin2G(code, addr)) {
code.call(f); code.call(f);
} else { } else {

View file

@ -10,7 +10,7 @@
namespace Core { namespace Core {
/// Generic ARM11 CPU interface /// Generic ARMv8 CPU interface
class ARM_Interface : NonCopyable { class ARM_Interface : NonCopyable {
public: public:
virtual ~ARM_Interface() {} virtual ~ARM_Interface() {}
@ -19,9 +19,9 @@ public:
std::array<u64, 31> cpu_registers; std::array<u64, 31> cpu_registers;
u64 sp; u64 sp;
u64 pc; u64 pc;
u64 cpsr; u64 pstate;
std::array<u128, 32> fpu_registers; std::array<u128, 32> vector_registers;
u64 fpscr; u64 fpcr;
}; };
/// Runs the CPU until an event happens /// Runs the CPU until an event happens
@ -31,11 +31,11 @@ public:
virtual void Step() = 0; virtual void Step() = 0;
/// Maps a backing memory region for the CPU /// Maps a backing memory region for the CPU
virtual void MapBackingMemory(VAddr address, size_t size, u8* memory, virtual void MapBackingMemory(VAddr address, std::size_t size, u8* memory,
Kernel::VMAPermission perms) = 0; Kernel::VMAPermission perms) = 0;
/// Unmaps a region of memory that was previously mapped using MapBackingMemory /// Unmaps a region of memory that was previously mapped using MapBackingMemory
virtual void UnmapMemory(VAddr address, size_t size) = 0; virtual void UnmapMemory(VAddr address, std::size_t size) = 0;
/// Clear all instruction cache /// Clear all instruction cache
virtual void ClearInstructionCache() = 0; virtual void ClearInstructionCache() = 0;
@ -69,42 +69,50 @@ public:
*/ */
virtual void SetReg(int index, u64 value) = 0; virtual void SetReg(int index, u64 value) = 0;
virtual u128 GetExtReg(int index) const = 0; /**
* Gets the value of a specified vector register.
virtual void SetExtReg(int index, u128 value) = 0; *
* @param index The index of the vector register.
* @return the value within the vector register.
*/
virtual u128 GetVectorReg(int index) const = 0;
/** /**
* Gets the value of a VFP register * Sets a given value into a vector register.
* @param index Register index (0-31) *
* @return Returns the value in the register * @param index The index of the vector register.
* @param value The new value to place in the register.
*/ */
virtual u32 GetVFPReg(int index) const = 0; virtual void SetVectorReg(int index, u128 value) = 0;
/** /**
* Sets a VFP register to the given value * Get the current PSTATE register
* @param index Register index (0-31) * @return Returns the value of the PSTATE register
* @param value Value to set register to
*/ */
virtual void SetVFPReg(int index, u32 value) = 0; virtual u32 GetPSTATE() const = 0;
/** /**
* Get the current CPSR register * Set the current PSTATE register
* @return Returns the value of the CPSR register * @param pstate Value to set PSTATE to
*/ */
virtual u32 GetCPSR() const = 0; virtual void SetPSTATE(u32 pstate) = 0;
/**
* Set the current CPSR register
* @param cpsr Value to set CPSR to
*/
virtual void SetCPSR(u32 cpsr) = 0;
virtual VAddr GetTlsAddress() const = 0; virtual VAddr GetTlsAddress() const = 0;
virtual void SetTlsAddress(VAddr address) = 0; virtual void SetTlsAddress(VAddr address) = 0;
/**
* Gets the value within the TPIDR_EL0 (read/write software thread ID) register.
*
* @return the value within the register.
*/
virtual u64 GetTPIDR_EL0() const = 0; virtual u64 GetTPIDR_EL0() const = 0;
/**
* Sets a new value within the TPIDR_EL0 (read/write software thread ID) register.
*
* @param value The new value to place in the register.
*/
virtual void SetTPIDR_EL0(u64 value) = 0; virtual void SetTPIDR_EL0(u64 value) = 0;
/** /**
@ -119,6 +127,7 @@ public:
*/ */
virtual void LoadContext(const ThreadContext& ctx) = 0; virtual void LoadContext(const ThreadContext& ctx) = 0;
/// Clears the exclusive monitor's state.
virtual void ClearExclusiveState() = 0; virtual void ClearExclusiveState() = 0;
/// Prepare core for thread reschedule (if needed to correctly handle state) /// Prepare core for thread reschedule (if needed to correctly handle state)

View file

@ -58,7 +58,7 @@ public:
Memory::Write64(vaddr + 8, value[1]); Memory::Write64(vaddr + 8, value[1]);
} }
void InterpreterFallback(u64 pc, size_t num_instructions) override { void InterpreterFallback(u64 pc, std::size_t num_instructions) override {
LOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc, LOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc,
num_instructions, MemoryReadCode(pc)); num_instructions, MemoryReadCode(pc));
@ -81,7 +81,7 @@ public:
return; return;
default: default:
ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:X})", ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:X})",
static_cast<size_t>(exception), pc); static_cast<std::size_t>(exception), pc);
} }
} }
@ -110,7 +110,7 @@ public:
} }
ARM_Dynarmic& parent; ARM_Dynarmic& parent;
size_t num_interpreted_instructions = 0; std::size_t num_interpreted_instructions = 0;
u64 tpidrro_el0 = 0; u64 tpidrro_el0 = 0;
u64 tpidr_el0 = 0; u64 tpidr_el0 = 0;
}; };
@ -157,7 +157,8 @@ void ARM_Dynarmic::Step() {
cb->InterpreterFallback(jit->GetPC(), 1); cb->InterpreterFallback(jit->GetPC(), 1);
} }
ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index) ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor,
std::size_t core_index)
: cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), core_index{core_index}, : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), core_index{core_index},
exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>(exclusive_monitor)} { exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>(exclusive_monitor)} {
ThreadContext ctx; ThreadContext ctx;
@ -168,12 +169,12 @@ ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor,
ARM_Dynarmic::~ARM_Dynarmic() = default; ARM_Dynarmic::~ARM_Dynarmic() = default;
void ARM_Dynarmic::MapBackingMemory(u64 address, size_t size, u8* memory, void ARM_Dynarmic::MapBackingMemory(u64 address, std::size_t size, u8* memory,
Kernel::VMAPermission perms) { Kernel::VMAPermission perms) {
inner_unicorn.MapBackingMemory(address, size, memory, perms); inner_unicorn.MapBackingMemory(address, size, memory, perms);
} }
void ARM_Dynarmic::UnmapMemory(u64 address, size_t size) { void ARM_Dynarmic::UnmapMemory(u64 address, std::size_t size) {
inner_unicorn.UnmapMemory(address, size); inner_unicorn.UnmapMemory(address, size);
} }
@ -193,29 +194,20 @@ void ARM_Dynarmic::SetReg(int index, u64 value) {
jit->SetRegister(index, value); jit->SetRegister(index, value);
} }
u128 ARM_Dynarmic::GetExtReg(int index) const { u128 ARM_Dynarmic::GetVectorReg(int index) const {
return jit->GetVector(index); return jit->GetVector(index);
} }
void ARM_Dynarmic::SetExtReg(int index, u128 value) { void ARM_Dynarmic::SetVectorReg(int index, u128 value) {
jit->SetVector(index, value); jit->SetVector(index, value);
} }
u32 ARM_Dynarmic::GetVFPReg(int /*index*/) const { u32 ARM_Dynarmic::GetPSTATE() const {
UNIMPLEMENTED();
return {};
}
void ARM_Dynarmic::SetVFPReg(int /*index*/, u32 /*value*/) {
UNIMPLEMENTED();
}
u32 ARM_Dynarmic::GetCPSR() const {
return jit->GetPstate(); return jit->GetPstate();
} }
void ARM_Dynarmic::SetCPSR(u32 cpsr) { void ARM_Dynarmic::SetPSTATE(u32 pstate) {
jit->SetPstate(cpsr); jit->SetPstate(pstate);
} }
u64 ARM_Dynarmic::GetTlsAddress() const { u64 ARM_Dynarmic::GetTlsAddress() const {
@ -238,18 +230,18 @@ void ARM_Dynarmic::SaveContext(ThreadContext& ctx) {
ctx.cpu_registers = jit->GetRegisters(); ctx.cpu_registers = jit->GetRegisters();
ctx.sp = jit->GetSP(); ctx.sp = jit->GetSP();
ctx.pc = jit->GetPC(); ctx.pc = jit->GetPC();
ctx.cpsr = jit->GetPstate(); ctx.pstate = jit->GetPstate();
ctx.fpu_registers = jit->GetVectors(); ctx.vector_registers = jit->GetVectors();
ctx.fpscr = jit->GetFpcr(); ctx.fpcr = jit->GetFpcr();
} }
void ARM_Dynarmic::LoadContext(const ThreadContext& ctx) { void ARM_Dynarmic::LoadContext(const ThreadContext& ctx) {
jit->SetRegisters(ctx.cpu_registers); jit->SetRegisters(ctx.cpu_registers);
jit->SetSP(ctx.sp); jit->SetSP(ctx.sp);
jit->SetPC(ctx.pc); jit->SetPC(ctx.pc);
jit->SetPstate(static_cast<u32>(ctx.cpsr)); jit->SetPstate(static_cast<u32>(ctx.pstate));
jit->SetVectors(ctx.fpu_registers); jit->SetVectors(ctx.vector_registers);
jit->SetFpcr(static_cast<u32>(ctx.fpscr)); jit->SetFpcr(static_cast<u32>(ctx.fpcr));
} }
void ARM_Dynarmic::PrepareReschedule() { void ARM_Dynarmic::PrepareReschedule() {
@ -269,10 +261,10 @@ void ARM_Dynarmic::PageTableChanged() {
current_page_table = Memory::GetCurrentPageTable(); current_page_table = Memory::GetCurrentPageTable();
} }
DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(size_t core_count) : monitor(core_count) {} DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(std::size_t core_count) : monitor(core_count) {}
DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default; DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default;
void DynarmicExclusiveMonitor::SetExclusive(size_t core_index, VAddr addr) { void DynarmicExclusiveMonitor::SetExclusive(std::size_t core_index, VAddr addr) {
// Size doesn't actually matter. // Size doesn't actually matter.
monitor.Mark(core_index, addr, 16); monitor.Mark(core_index, addr, 16);
} }
@ -281,30 +273,30 @@ void DynarmicExclusiveMonitor::ClearExclusive() {
monitor.Clear(); monitor.Clear();
} }
bool DynarmicExclusiveMonitor::ExclusiveWrite8(size_t core_index, VAddr vaddr, u8 value) { bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 1, return monitor.DoExclusiveOperation(core_index, vaddr, 1,
[&] { Memory::Write8(vaddr, value); }); [&] { Memory::Write8(vaddr, value); });
} }
bool DynarmicExclusiveMonitor::ExclusiveWrite16(size_t core_index, VAddr vaddr, u16 value) { bool DynarmicExclusiveMonitor::ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 2, return monitor.DoExclusiveOperation(core_index, vaddr, 2,
[&] { Memory::Write16(vaddr, value); }); [&] { Memory::Write16(vaddr, value); });
} }
bool DynarmicExclusiveMonitor::ExclusiveWrite32(size_t core_index, VAddr vaddr, u32 value) { bool DynarmicExclusiveMonitor::ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 4, return monitor.DoExclusiveOperation(core_index, vaddr, 4,
[&] { Memory::Write32(vaddr, value); }); [&] { Memory::Write32(vaddr, value); });
} }
bool DynarmicExclusiveMonitor::ExclusiveWrite64(size_t core_index, VAddr vaddr, u64 value) { bool DynarmicExclusiveMonitor::ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 8, return monitor.DoExclusiveOperation(core_index, vaddr, 8,
[&] { Memory::Write64(vaddr, value); }); [&] { Memory::Write64(vaddr, value); });
} }
bool DynarmicExclusiveMonitor::ExclusiveWrite128(size_t core_index, VAddr vaddr, u128 value) { bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 16, [&] { return monitor.DoExclusiveOperation(core_index, vaddr, 16, [&] {
Memory::Write64(vaddr, value[0]); Memory::Write64(vaddr + 0, value[0]);
Memory::Write64(vaddr, value[1]); Memory::Write64(vaddr + 8, value[1]);
}); });
} }

View file

@ -19,24 +19,22 @@ class DynarmicExclusiveMonitor;
class ARM_Dynarmic final : public ARM_Interface { class ARM_Dynarmic final : public ARM_Interface {
public: public:
ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index); ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, std::size_t core_index);
~ARM_Dynarmic(); ~ARM_Dynarmic();
void MapBackingMemory(VAddr address, size_t size, u8* memory, void MapBackingMemory(VAddr address, std::size_t size, u8* memory,
Kernel::VMAPermission perms) override; Kernel::VMAPermission perms) override;
void UnmapMemory(u64 address, size_t size) override; void UnmapMemory(u64 address, std::size_t size) override;
void SetPC(u64 pc) override; void SetPC(u64 pc) override;
u64 GetPC() const override; u64 GetPC() const override;
u64 GetReg(int index) const override; u64 GetReg(int index) const override;
void SetReg(int index, u64 value) override; void SetReg(int index, u64 value) override;
u128 GetExtReg(int index) const override; u128 GetVectorReg(int index) const override;
void SetExtReg(int index, u128 value) override; void SetVectorReg(int index, u128 value) override;
u32 GetVFPReg(int index) const override; u32 GetPSTATE() const override;
void SetVFPReg(int index, u32 value) override; void SetPSTATE(u32 pstate) override;
u32 GetCPSR() const override;
void Run() override; void Run() override;
void Step() override; void Step() override;
void SetCPSR(u32 cpsr) override;
VAddr GetTlsAddress() const override; VAddr GetTlsAddress() const override;
void SetTlsAddress(VAddr address) override; void SetTlsAddress(VAddr address) override;
void SetTPIDR_EL0(u64 value) override; void SetTPIDR_EL0(u64 value) override;
@ -59,7 +57,7 @@ private:
std::unique_ptr<Dynarmic::A64::Jit> jit; std::unique_ptr<Dynarmic::A64::Jit> jit;
ARM_Unicorn inner_unicorn; ARM_Unicorn inner_unicorn;
size_t core_index; std::size_t core_index;
std::shared_ptr<DynarmicExclusiveMonitor> exclusive_monitor; std::shared_ptr<DynarmicExclusiveMonitor> exclusive_monitor;
Memory::PageTable* current_page_table = nullptr; Memory::PageTable* current_page_table = nullptr;
@ -67,17 +65,17 @@ private:
class DynarmicExclusiveMonitor final : public ExclusiveMonitor { class DynarmicExclusiveMonitor final : public ExclusiveMonitor {
public: public:
explicit DynarmicExclusiveMonitor(size_t core_count); explicit DynarmicExclusiveMonitor(std::size_t core_count);
~DynarmicExclusiveMonitor(); ~DynarmicExclusiveMonitor();
void SetExclusive(size_t core_index, VAddr addr) override; void SetExclusive(std::size_t core_index, VAddr addr) override;
void ClearExclusive() override; void ClearExclusive() override;
bool ExclusiveWrite8(size_t core_index, VAddr vaddr, u8 value) override; bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) override;
bool ExclusiveWrite16(size_t core_index, VAddr vaddr, u16 value) override; bool ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) override;
bool ExclusiveWrite32(size_t core_index, VAddr vaddr, u32 value) override; bool ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) override;
bool ExclusiveWrite64(size_t core_index, VAddr vaddr, u64 value) override; bool ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) override;
bool ExclusiveWrite128(size_t core_index, VAddr vaddr, u128 value) override; bool ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) override;
private: private:
friend class ARM_Dynarmic; friend class ARM_Dynarmic;

View file

@ -12,14 +12,14 @@ class ExclusiveMonitor {
public: public:
virtual ~ExclusiveMonitor(); virtual ~ExclusiveMonitor();
virtual void SetExclusive(size_t core_index, VAddr addr) = 0; virtual void SetExclusive(std::size_t core_index, VAddr addr) = 0;
virtual void ClearExclusive() = 0; virtual void ClearExclusive() = 0;
virtual bool ExclusiveWrite8(size_t core_index, VAddr vaddr, u8 value) = 0; virtual bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) = 0;
virtual bool ExclusiveWrite16(size_t core_index, VAddr vaddr, u16 value) = 0; virtual bool ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) = 0;
virtual bool ExclusiveWrite32(size_t core_index, VAddr vaddr, u32 value) = 0; virtual bool ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) = 0;
virtual bool ExclusiveWrite64(size_t core_index, VAddr vaddr, u64 value) = 0; virtual bool ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) = 0;
virtual bool ExclusiveWrite128(size_t core_index, VAddr vaddr, u128 value) = 0; virtual bool ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) = 0;
}; };
} // namespace Core } // namespace Core

View file

@ -90,12 +90,12 @@ ARM_Unicorn::~ARM_Unicorn() {
CHECKED(uc_close(uc)); CHECKED(uc_close(uc));
} }
void ARM_Unicorn::MapBackingMemory(VAddr address, size_t size, u8* memory, void ARM_Unicorn::MapBackingMemory(VAddr address, std::size_t size, u8* memory,
Kernel::VMAPermission perms) { Kernel::VMAPermission perms) {
CHECKED(uc_mem_map_ptr(uc, address, size, static_cast<u32>(perms), memory)); CHECKED(uc_mem_map_ptr(uc, address, size, static_cast<u32>(perms), memory));
} }
void ARM_Unicorn::UnmapMemory(VAddr address, size_t size) { void ARM_Unicorn::UnmapMemory(VAddr address, std::size_t size) {
CHECKED(uc_mem_unmap(uc, address, size)); CHECKED(uc_mem_unmap(uc, address, size));
} }
@ -131,33 +131,24 @@ void ARM_Unicorn::SetReg(int regn, u64 val) {
CHECKED(uc_reg_write(uc, treg, &val)); CHECKED(uc_reg_write(uc, treg, &val));
} }
u128 ARM_Unicorn::GetExtReg(int /*index*/) const { u128 ARM_Unicorn::GetVectorReg(int /*index*/) const {
UNIMPLEMENTED(); UNIMPLEMENTED();
static constexpr u128 res{}; static constexpr u128 res{};
return res; return res;
} }
void ARM_Unicorn::SetExtReg(int /*index*/, u128 /*value*/) { void ARM_Unicorn::SetVectorReg(int /*index*/, u128 /*value*/) {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
u32 ARM_Unicorn::GetVFPReg(int /*index*/) const { u32 ARM_Unicorn::GetPSTATE() const {
UNIMPLEMENTED();
return {};
}
void ARM_Unicorn::SetVFPReg(int /*index*/, u32 /*value*/) {
UNIMPLEMENTED();
}
u32 ARM_Unicorn::GetCPSR() const {
u64 nzcv{}; u64 nzcv{};
CHECKED(uc_reg_read(uc, UC_ARM64_REG_NZCV, &nzcv)); CHECKED(uc_reg_read(uc, UC_ARM64_REG_NZCV, &nzcv));
return static_cast<u32>(nzcv); return static_cast<u32>(nzcv);
} }
void ARM_Unicorn::SetCPSR(u32 cpsr) { void ARM_Unicorn::SetPSTATE(u32 pstate) {
u64 nzcv = cpsr; u64 nzcv = pstate;
CHECKED(uc_reg_write(uc, UC_ARM64_REG_NZCV, &nzcv)); CHECKED(uc_reg_write(uc, UC_ARM64_REG_NZCV, &nzcv));
} }
@ -219,7 +210,7 @@ void ARM_Unicorn::SaveContext(ThreadContext& ctx) {
CHECKED(uc_reg_read(uc, UC_ARM64_REG_SP, &ctx.sp)); CHECKED(uc_reg_read(uc, UC_ARM64_REG_SP, &ctx.sp));
CHECKED(uc_reg_read(uc, UC_ARM64_REG_PC, &ctx.pc)); CHECKED(uc_reg_read(uc, UC_ARM64_REG_PC, &ctx.pc));
CHECKED(uc_reg_read(uc, UC_ARM64_REG_NZCV, &ctx.cpsr)); CHECKED(uc_reg_read(uc, UC_ARM64_REG_NZCV, &ctx.pstate));
for (auto i = 0; i < 29; ++i) { for (auto i = 0; i < 29; ++i) {
uregs[i] = UC_ARM64_REG_X0 + i; uregs[i] = UC_ARM64_REG_X0 + i;
@ -234,7 +225,7 @@ void ARM_Unicorn::SaveContext(ThreadContext& ctx) {
for (int i = 0; i < 32; ++i) { for (int i = 0; i < 32; ++i) {
uregs[i] = UC_ARM64_REG_Q0 + i; uregs[i] = UC_ARM64_REG_Q0 + i;
tregs[i] = &ctx.fpu_registers[i]; tregs[i] = &ctx.vector_registers[i];
} }
CHECKED(uc_reg_read_batch(uc, uregs, tregs, 32)); CHECKED(uc_reg_read_batch(uc, uregs, tregs, 32));
@ -246,7 +237,7 @@ void ARM_Unicorn::LoadContext(const ThreadContext& ctx) {
CHECKED(uc_reg_write(uc, UC_ARM64_REG_SP, &ctx.sp)); CHECKED(uc_reg_write(uc, UC_ARM64_REG_SP, &ctx.sp));
CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &ctx.pc)); CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &ctx.pc));
CHECKED(uc_reg_write(uc, UC_ARM64_REG_NZCV, &ctx.cpsr)); CHECKED(uc_reg_write(uc, UC_ARM64_REG_NZCV, &ctx.pstate));
for (int i = 0; i < 29; ++i) { for (int i = 0; i < 29; ++i) {
uregs[i] = UC_ARM64_REG_X0 + i; uregs[i] = UC_ARM64_REG_X0 + i;
@ -261,7 +252,7 @@ void ARM_Unicorn::LoadContext(const ThreadContext& ctx) {
for (auto i = 0; i < 32; ++i) { for (auto i = 0; i < 32; ++i) {
uregs[i] = UC_ARM64_REG_Q0 + i; uregs[i] = UC_ARM64_REG_Q0 + i;
tregs[i] = (void*)&ctx.fpu_registers[i]; tregs[i] = (void*)&ctx.vector_registers[i];
} }
CHECKED(uc_reg_write_batch(uc, uregs, tregs, 32)); CHECKED(uc_reg_write_batch(uc, uregs, tregs, 32));

View file

@ -15,19 +15,17 @@ class ARM_Unicorn final : public ARM_Interface {
public: public:
ARM_Unicorn(); ARM_Unicorn();
~ARM_Unicorn(); ~ARM_Unicorn();
void MapBackingMemory(VAddr address, size_t size, u8* memory, void MapBackingMemory(VAddr address, std::size_t size, u8* memory,
Kernel::VMAPermission perms) override; Kernel::VMAPermission perms) override;
void UnmapMemory(VAddr address, size_t size) override; void UnmapMemory(VAddr address, std::size_t size) override;
void SetPC(u64 pc) override; void SetPC(u64 pc) override;
u64 GetPC() const override; u64 GetPC() const override;
u64 GetReg(int index) const override; u64 GetReg(int index) const override;
void SetReg(int index, u64 value) override; void SetReg(int index, u64 value) override;
u128 GetExtReg(int index) const override; u128 GetVectorReg(int index) const override;
void SetExtReg(int index, u128 value) override; void SetVectorReg(int index, u128 value) override;
u32 GetVFPReg(int index) const override; u32 GetPSTATE() const override;
void SetVFPReg(int index, u32 value) override; void SetPSTATE(u32 pstate) override;
u32 GetCPSR() const override;
void SetCPSR(u32 cpsr) override;
VAddr GetTlsAddress() const override; VAddr GetTlsAddress() const override;
void SetTlsAddress(VAddr address) override; void SetTlsAddress(VAddr address) override;
void SetTPIDR_EL0(u64 value) override; void SetTPIDR_EL0(u64 value) override;

View file

@ -140,7 +140,7 @@ struct System::Impl {
cpu_barrier = std::make_shared<CpuBarrier>(); cpu_barrier = std::make_shared<CpuBarrier>();
cpu_exclusive_monitor = Cpu::MakeExclusiveMonitor(cpu_cores.size()); cpu_exclusive_monitor = Cpu::MakeExclusiveMonitor(cpu_cores.size());
for (size_t index = 0; index < cpu_cores.size(); ++index) { for (std::size_t index = 0; index < cpu_cores.size(); ++index) {
cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index); cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index);
} }
@ -161,7 +161,7 @@ struct System::Impl {
// CPU core 0 is run on the main thread // CPU core 0 is run on the main thread
thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0];
if (Settings::values.use_multi_core) { if (Settings::values.use_multi_core) {
for (size_t index = 0; index < cpu_core_threads.size(); ++index) { for (std::size_t index = 0; index < cpu_core_threads.size(); ++index) {
cpu_core_threads[index] = cpu_core_threads[index] =
std::make_unique<std::thread>(RunCpuCore, cpu_cores[index + 1]); std::make_unique<std::thread>(RunCpuCore, cpu_cores[index + 1]);
thread_to_cpu[cpu_core_threads[index]->get_id()] = cpu_cores[index + 1]; thread_to_cpu[cpu_core_threads[index]->get_id()] = cpu_cores[index + 1];
@ -285,7 +285,7 @@ struct System::Impl {
std::shared_ptr<CpuBarrier> cpu_barrier; std::shared_ptr<CpuBarrier> cpu_barrier;
std::array<std::shared_ptr<Cpu>, NUM_CPU_CORES> cpu_cores; std::array<std::shared_ptr<Cpu>, NUM_CPU_CORES> cpu_cores;
std::array<std::unique_ptr<std::thread>, NUM_CPU_CORES - 1> cpu_core_threads; std::array<std::unique_ptr<std::thread>, NUM_CPU_CORES - 1> cpu_core_threads;
size_t active_core{}; ///< Active core, only used in single thread mode std::size_t active_core{}; ///< Active core, only used in single thread mode
/// Service manager /// Service manager
std::shared_ptr<Service::SM::ServiceManager> service_manager; std::shared_ptr<Service::SM::ServiceManager> service_manager;
@ -348,7 +348,7 @@ ARM_Interface& System::CurrentArmInterface() {
return CurrentCpuCore().ArmInterface(); return CurrentCpuCore().ArmInterface();
} }
size_t System::CurrentCoreIndex() { std::size_t System::CurrentCoreIndex() {
return CurrentCpuCore().CoreIndex(); return CurrentCpuCore().CoreIndex();
} }
@ -356,7 +356,7 @@ Kernel::Scheduler& System::CurrentScheduler() {
return *CurrentCpuCore().Scheduler(); return *CurrentCpuCore().Scheduler();
} }
const std::shared_ptr<Kernel::Scheduler>& System::Scheduler(size_t core_index) { const std::shared_ptr<Kernel::Scheduler>& System::Scheduler(std::size_t core_index) {
ASSERT(core_index < NUM_CPU_CORES); ASSERT(core_index < NUM_CPU_CORES);
return impl->cpu_cores[core_index]->Scheduler(); return impl->cpu_cores[core_index]->Scheduler();
} }
@ -369,12 +369,12 @@ const Kernel::SharedPtr<Kernel::Process>& System::CurrentProcess() const {
return impl->kernel.CurrentProcess(); return impl->kernel.CurrentProcess();
} }
ARM_Interface& System::ArmInterface(size_t core_index) { ARM_Interface& System::ArmInterface(std::size_t core_index) {
ASSERT(core_index < NUM_CPU_CORES); ASSERT(core_index < NUM_CPU_CORES);
return impl->cpu_cores[core_index]->ArmInterface(); return impl->cpu_cores[core_index]->ArmInterface();
} }
Cpu& System::CpuCore(size_t core_index) { Cpu& System::CpuCore(std::size_t core_index) {
ASSERT(core_index < NUM_CPU_CORES); ASSERT(core_index < NUM_CPU_CORES);
return *impl->cpu_cores[core_index]; return *impl->cpu_cores[core_index];
} }

View file

@ -145,16 +145,16 @@ public:
ARM_Interface& CurrentArmInterface(); ARM_Interface& CurrentArmInterface();
/// Gets the index of the currently running CPU core /// Gets the index of the currently running CPU core
size_t CurrentCoreIndex(); std::size_t CurrentCoreIndex();
/// Gets the scheduler for the CPU core that is currently running /// Gets the scheduler for the CPU core that is currently running
Kernel::Scheduler& CurrentScheduler(); Kernel::Scheduler& CurrentScheduler();
/// Gets an ARM interface to the CPU core with the specified index /// Gets an ARM interface to the CPU core with the specified index
ARM_Interface& ArmInterface(size_t core_index); ARM_Interface& ArmInterface(std::size_t core_index);
/// Gets a CPU interface to the CPU core with the specified index /// Gets a CPU interface to the CPU core with the specified index
Cpu& CpuCore(size_t core_index); Cpu& CpuCore(std::size_t core_index);
/// Gets the exclusive monitor /// Gets the exclusive monitor
ExclusiveMonitor& Monitor(); ExclusiveMonitor& Monitor();
@ -172,7 +172,7 @@ public:
const VideoCore::RendererBase& Renderer() const; const VideoCore::RendererBase& Renderer() const;
/// Gets the scheduler for the CPU core with the specified index /// Gets the scheduler for the CPU core with the specified index
const std::shared_ptr<Kernel::Scheduler>& Scheduler(size_t core_index); const std::shared_ptr<Kernel::Scheduler>& Scheduler(std::size_t core_index);
/// Provides a reference to the current process /// Provides a reference to the current process
Kernel::SharedPtr<Kernel::Process>& CurrentProcess(); Kernel::SharedPtr<Kernel::Process>& CurrentProcess();

View file

@ -9,6 +9,7 @@
#ifdef ARCHITECTURE_x86_64 #ifdef ARCHITECTURE_x86_64
#include "core/arm/dynarmic/arm_dynarmic.h" #include "core/arm/dynarmic/arm_dynarmic.h"
#endif #endif
#include "core/arm/exclusive_monitor.h"
#include "core/arm/unicorn/arm_unicorn.h" #include "core/arm/unicorn/arm_unicorn.h"
#include "core/core_cpu.h" #include "core/core_cpu.h"
#include "core/core_timing.h" #include "core/core_timing.h"
@ -49,7 +50,7 @@ bool CpuBarrier::Rendezvous() {
} }
Cpu::Cpu(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, Cpu::Cpu(std::shared_ptr<ExclusiveMonitor> exclusive_monitor,
std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index) std::shared_ptr<CpuBarrier> cpu_barrier, std::size_t core_index)
: cpu_barrier{std::move(cpu_barrier)}, core_index{core_index} { : cpu_barrier{std::move(cpu_barrier)}, core_index{core_index} {
if (Settings::values.use_cpu_jit) { if (Settings::values.use_cpu_jit) {
@ -66,7 +67,9 @@ Cpu::Cpu(std::shared_ptr<ExclusiveMonitor> exclusive_monitor,
scheduler = std::make_shared<Kernel::Scheduler>(arm_interface.get()); scheduler = std::make_shared<Kernel::Scheduler>(arm_interface.get());
} }
std::shared_ptr<ExclusiveMonitor> Cpu::MakeExclusiveMonitor(size_t num_cores) { Cpu::~Cpu() = default;
std::shared_ptr<ExclusiveMonitor> Cpu::MakeExclusiveMonitor(std::size_t num_cores) {
if (Settings::values.use_cpu_jit) { if (Settings::values.use_cpu_jit) {
#ifdef ARCHITECTURE_x86_64 #ifdef ARCHITECTURE_x86_64
return std::make_shared<DynarmicExclusiveMonitor>(num_cores); return std::make_shared<DynarmicExclusiveMonitor>(num_cores);

View file

@ -6,11 +6,10 @@
#include <atomic> #include <atomic>
#include <condition_variable> #include <condition_variable>
#include <cstddef>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <string>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/arm/exclusive_monitor.h"
namespace Kernel { namespace Kernel {
class Scheduler; class Scheduler;
@ -19,6 +18,7 @@ class Scheduler;
namespace Core { namespace Core {
class ARM_Interface; class ARM_Interface;
class ExclusiveMonitor;
constexpr unsigned NUM_CPU_CORES{4}; constexpr unsigned NUM_CPU_CORES{4};
@ -42,7 +42,8 @@ private:
class Cpu { class Cpu {
public: public:
Cpu(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, Cpu(std::shared_ptr<ExclusiveMonitor> exclusive_monitor,
std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index); std::shared_ptr<CpuBarrier> cpu_barrier, std::size_t core_index);
~Cpu();
void RunLoop(bool tight_loop = true); void RunLoop(bool tight_loop = true);
@ -66,11 +67,11 @@ public:
return core_index == 0; return core_index == 0;
} }
size_t CoreIndex() const { std::size_t CoreIndex() const {
return core_index; return core_index;
} }
static std::shared_ptr<ExclusiveMonitor> MakeExclusiveMonitor(size_t num_cores); static std::shared_ptr<ExclusiveMonitor> MakeExclusiveMonitor(std::size_t num_cores);
private: private:
void Reschedule(); void Reschedule();
@ -80,7 +81,7 @@ private:
std::shared_ptr<Kernel::Scheduler> scheduler; std::shared_ptr<Kernel::Scheduler> scheduler;
std::atomic<bool> reschedule_pending = false; std::atomic<bool> reschedule_pending = false;
size_t core_index; std::size_t core_index;
}; };
} // namespace Core } // namespace Core

View file

@ -10,9 +10,9 @@
namespace Core::Crypto { namespace Core::Crypto {
namespace { namespace {
std::vector<u8> CalculateNintendoTweak(size_t sector_id) { std::vector<u8> CalculateNintendoTweak(std::size_t sector_id) {
std::vector<u8> out(0x10); std::vector<u8> out(0x10);
for (size_t i = 0xF; i <= 0xF; --i) { for (std::size_t i = 0xF; i <= 0xF; --i) {
out[i] = sector_id & 0xFF; out[i] = sector_id & 0xFF;
sector_id >>= 8; sector_id >>= 8;
} }
@ -20,11 +20,14 @@ std::vector<u8> CalculateNintendoTweak(size_t sector_id) {
} }
} // Anonymous namespace } // Anonymous namespace
static_assert(static_cast<size_t>(Mode::CTR) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_CTR), static_assert(static_cast<std::size_t>(Mode::CTR) ==
static_cast<std::size_t>(MBEDTLS_CIPHER_AES_128_CTR),
"CTR has incorrect value."); "CTR has incorrect value.");
static_assert(static_cast<size_t>(Mode::ECB) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_ECB), static_assert(static_cast<std::size_t>(Mode::ECB) ==
static_cast<std::size_t>(MBEDTLS_CIPHER_AES_128_ECB),
"ECB has incorrect value."); "ECB has incorrect value.");
static_assert(static_cast<size_t>(Mode::XTS) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_XTS), static_assert(static_cast<std::size_t>(Mode::XTS) ==
static_cast<std::size_t>(MBEDTLS_CIPHER_AES_128_XTS),
"XTS has incorrect value."); "XTS has incorrect value.");
// Structure to hide mbedtls types from header file // Structure to hide mbedtls types from header file
@ -33,7 +36,7 @@ struct CipherContext {
mbedtls_cipher_context_t decryption_context; mbedtls_cipher_context_t decryption_context;
}; };
template <typename Key, size_t KeySize> template <typename Key, std::size_t KeySize>
Crypto::AESCipher<Key, KeySize>::AESCipher(Key key, Mode mode) Crypto::AESCipher<Key, KeySize>::AESCipher(Key key, Mode mode)
: ctx(std::make_unique<CipherContext>()) { : ctx(std::make_unique<CipherContext>()) {
mbedtls_cipher_init(&ctx->encryption_context); mbedtls_cipher_init(&ctx->encryption_context);
@ -54,26 +57,26 @@ Crypto::AESCipher<Key, KeySize>::AESCipher(Key key, Mode mode)
//"Failed to set key on mbedtls ciphers."); //"Failed to set key on mbedtls ciphers.");
} }
template <typename Key, size_t KeySize> template <typename Key, std::size_t KeySize>
AESCipher<Key, KeySize>::~AESCipher() { AESCipher<Key, KeySize>::~AESCipher() {
mbedtls_cipher_free(&ctx->encryption_context); mbedtls_cipher_free(&ctx->encryption_context);
mbedtls_cipher_free(&ctx->decryption_context); mbedtls_cipher_free(&ctx->decryption_context);
} }
template <typename Key, size_t KeySize> template <typename Key, std::size_t KeySize>
void AESCipher<Key, KeySize>::SetIV(std::vector<u8> iv) { void AESCipher<Key, KeySize>::SetIV(std::vector<u8> iv) {
ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, iv.data(), iv.size()) || ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, iv.data(), iv.size()) ||
mbedtls_cipher_set_iv(&ctx->decryption_context, iv.data(), iv.size())) == 0, mbedtls_cipher_set_iv(&ctx->decryption_context, iv.data(), iv.size())) == 0,
"Failed to set IV on mbedtls ciphers."); "Failed to set IV on mbedtls ciphers.");
} }
template <typename Key, size_t KeySize> template <typename Key, std::size_t KeySize>
void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op op) const { void AESCipher<Key, KeySize>::Transcode(const u8* src, std::size_t size, u8* dest, Op op) const {
auto* const context = op == Op::Encrypt ? &ctx->encryption_context : &ctx->decryption_context; auto* const context = op == Op::Encrypt ? &ctx->encryption_context : &ctx->decryption_context;
mbedtls_cipher_reset(context); mbedtls_cipher_reset(context);
size_t written = 0; std::size_t written = 0;
if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) { if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) {
mbedtls_cipher_update(context, src, size, dest, &written); mbedtls_cipher_update(context, src, size, dest, &written);
if (written != size) { if (written != size) {
@ -90,8 +93,8 @@ void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op
return; return;
} }
for (size_t offset = 0; offset < size; offset += block_size) { for (std::size_t offset = 0; offset < size; offset += block_size) {
auto length = std::min<size_t>(block_size, size - offset); auto length = std::min<std::size_t>(block_size, size - offset);
mbedtls_cipher_update(context, src + offset, length, dest + offset, &written); mbedtls_cipher_update(context, src + offset, length, dest + offset, &written);
if (written != length) { if (written != length) {
if (length < block_size) { if (length < block_size) {
@ -110,12 +113,12 @@ void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op
mbedtls_cipher_finish(context, nullptr, nullptr); mbedtls_cipher_finish(context, nullptr, nullptr);
} }
template <typename Key, size_t KeySize> template <typename Key, std::size_t KeySize>
void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id, void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, std::size_t size, u8* dest,
size_t sector_size, Op op) { std::size_t sector_id, std::size_t sector_size, Op op) {
ASSERT_MSG(size % sector_size == 0, "XTS decryption size must be a multiple of sector size."); ASSERT_MSG(size % sector_size == 0, "XTS decryption size must be a multiple of sector size.");
for (size_t i = 0; i < size; i += sector_size) { for (std::size_t i = 0; i < size; i += sector_size) {
SetIV(CalculateNintendoTweak(sector_id++)); SetIV(CalculateNintendoTweak(sector_id++));
Transcode<u8, u8>(src + i, sector_size, dest + i, op); Transcode<u8, u8>(src + i, sector_size, dest + i, op);
} }

View file

@ -25,7 +25,7 @@ enum class Op {
Decrypt, Decrypt,
}; };
template <typename Key, size_t KeySize = sizeof(Key)> template <typename Key, std::size_t KeySize = sizeof(Key)>
class AESCipher { class AESCipher {
static_assert(std::is_same_v<Key, std::array<u8, KeySize>>, "Key must be std::array of u8."); static_assert(std::is_same_v<Key, std::array<u8, KeySize>>, "Key must be std::array of u8.");
static_assert(KeySize == 0x10 || KeySize == 0x20, "KeySize must be 128 or 256."); static_assert(KeySize == 0x10 || KeySize == 0x20, "KeySize must be 128 or 256.");
@ -38,25 +38,25 @@ public:
void SetIV(std::vector<u8> iv); void SetIV(std::vector<u8> iv);
template <typename Source, typename Dest> template <typename Source, typename Dest>
void Transcode(const Source* src, size_t size, Dest* dest, Op op) const { void Transcode(const Source* src, std::size_t size, Dest* dest, Op op) const {
static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>, static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>,
"Transcode source and destination types must be trivially copyable."); "Transcode source and destination types must be trivially copyable.");
Transcode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), op); Transcode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), op);
} }
void Transcode(const u8* src, size_t size, u8* dest, Op op) const; void Transcode(const u8* src, std::size_t size, u8* dest, Op op) const;
template <typename Source, typename Dest> template <typename Source, typename Dest>
void XTSTranscode(const Source* src, size_t size, Dest* dest, size_t sector_id, void XTSTranscode(const Source* src, std::size_t size, Dest* dest, std::size_t sector_id,
size_t sector_size, Op op) { std::size_t sector_size, Op op) {
static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>, static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>,
"XTSTranscode source and destination types must be trivially copyable."); "XTSTranscode source and destination types must be trivially copyable.");
XTSTranscode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), sector_id, XTSTranscode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), sector_id,
sector_size, op); sector_size, op);
} }
void XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id, size_t sector_size, void XTSTranscode(const u8* src, std::size_t size, u8* dest, std::size_t sector_id,
Op op); std::size_t sector_size, Op op);
private: private:
std::unique_ptr<CipherContext> ctx; std::unique_ptr<CipherContext> ctx;

View file

@ -8,11 +8,12 @@
namespace Core::Crypto { namespace Core::Crypto {
CTREncryptionLayer::CTREncryptionLayer(FileSys::VirtualFile base_, Key128 key_, size_t base_offset) CTREncryptionLayer::CTREncryptionLayer(FileSys::VirtualFile base_, Key128 key_,
std::size_t base_offset)
: EncryptionLayer(std::move(base_)), base_offset(base_offset), cipher(key_, Mode::CTR), : EncryptionLayer(std::move(base_)), base_offset(base_offset), cipher(key_, Mode::CTR),
iv(16, 0) {} iv(16, 0) {}
size_t CTREncryptionLayer::Read(u8* data, size_t length, size_t offset) const { std::size_t CTREncryptionLayer::Read(u8* data, std::size_t length, std::size_t offset) const {
if (length == 0) if (length == 0)
return 0; return 0;
@ -28,7 +29,7 @@ size_t CTREncryptionLayer::Read(u8* data, size_t length, size_t offset) const {
std::vector<u8> block = base->ReadBytes(0x10, offset - sector_offset); std::vector<u8> block = base->ReadBytes(0x10, offset - sector_offset);
UpdateIV(base_offset + offset - sector_offset); UpdateIV(base_offset + offset - sector_offset);
cipher.Transcode(block.data(), block.size(), block.data(), Op::Decrypt); cipher.Transcode(block.data(), block.size(), block.data(), Op::Decrypt);
size_t read = 0x10 - sector_offset; std::size_t read = 0x10 - sector_offset;
if (length + sector_offset < 0x10) { if (length + sector_offset < 0x10) {
std::memcpy(data, block.data() + sector_offset, std::min<u64>(length, read)); std::memcpy(data, block.data() + sector_offset, std::min<u64>(length, read));
@ -43,9 +44,9 @@ void CTREncryptionLayer::SetIV(const std::vector<u8>& iv_) {
iv.assign(iv_.cbegin(), iv_.cbegin() + length); iv.assign(iv_.cbegin(), iv_.cbegin() + length);
} }
void CTREncryptionLayer::UpdateIV(size_t offset) const { void CTREncryptionLayer::UpdateIV(std::size_t offset) const {
offset >>= 4; offset >>= 4;
for (size_t i = 0; i < 8; ++i) { for (std::size_t i = 0; i < 8; ++i) {
iv[16 - i - 1] = offset & 0xFF; iv[16 - i - 1] = offset & 0xFF;
offset >>= 8; offset >>= 8;
} }

View file

@ -14,20 +14,20 @@ namespace Core::Crypto {
// Sits on top of a VirtualFile and provides CTR-mode AES decription. // Sits on top of a VirtualFile and provides CTR-mode AES decription.
class CTREncryptionLayer : public EncryptionLayer { class CTREncryptionLayer : public EncryptionLayer {
public: public:
CTREncryptionLayer(FileSys::VirtualFile base, Key128 key, size_t base_offset); CTREncryptionLayer(FileSys::VirtualFile base, Key128 key, std::size_t base_offset);
size_t Read(u8* data, size_t length, size_t offset) const override; std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
void SetIV(const std::vector<u8>& iv); void SetIV(const std::vector<u8>& iv);
private: private:
size_t base_offset; std::size_t base_offset;
// Must be mutable as operations modify cipher contexts. // Must be mutable as operations modify cipher contexts.
mutable AESCipher<Key128> cipher; mutable AESCipher<Key128> cipher;
mutable std::vector<u8> iv; mutable std::vector<u8> iv;
void UpdateIV(size_t offset) const; void UpdateIV(std::size_t offset) const;
}; };
} // namespace Core::Crypto } // namespace Core::Crypto

View file

@ -12,11 +12,11 @@ std::string EncryptionLayer::GetName() const {
return base->GetName(); return base->GetName();
} }
size_t EncryptionLayer::GetSize() const { std::size_t EncryptionLayer::GetSize() const {
return base->GetSize(); return base->GetSize();
} }
bool EncryptionLayer::Resize(size_t new_size) { bool EncryptionLayer::Resize(std::size_t new_size) {
return false; return false;
} }
@ -32,7 +32,7 @@ bool EncryptionLayer::IsReadable() const {
return true; return true;
} }
size_t EncryptionLayer::Write(const u8* data, size_t length, size_t offset) { std::size_t EncryptionLayer::Write(const u8* data, std::size_t length, std::size_t offset) {
return 0; return 0;
} }

View file

@ -15,15 +15,15 @@ class EncryptionLayer : public FileSys::VfsFile {
public: public:
explicit EncryptionLayer(FileSys::VirtualFile base); explicit EncryptionLayer(FileSys::VirtualFile base);
size_t Read(u8* data, size_t length, size_t offset) const override = 0; std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override = 0;
std::string GetName() const override; std::string GetName() const override;
size_t GetSize() const override; std::size_t GetSize() const override;
bool Resize(size_t new_size) override; bool Resize(std::size_t new_size) override;
std::shared_ptr<FileSys::VfsDirectory> GetContainingDirectory() const override; std::shared_ptr<FileSys::VfsDirectory> GetContainingDirectory() const override;
bool IsWritable() const override; bool IsWritable() const override;
bool IsReadable() const override; bool IsReadable() const override;
size_t Write(const u8* data, size_t length, size_t offset) override; std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override;
bool Rename(std::string_view name) override; bool Rename(std::string_view name) override;
protected: protected:

View file

@ -54,7 +54,7 @@ boost::optional<Key128> DeriveSDSeed() {
return boost::none; return boost::none;
std::array<u8, 0x10> buffer{}; std::array<u8, 0x10> buffer{};
size_t offset = 0; std::size_t offset = 0;
for (; offset + 0x10 < save_43.GetSize(); ++offset) { for (; offset + 0x10 < save_43.GetSize(); ++offset) {
save_43.Seek(offset, SEEK_SET); save_43.Seek(offset, SEEK_SET);
save_43.ReadBytes(buffer.data(), buffer.size()); save_43.ReadBytes(buffer.data(), buffer.size());
@ -105,7 +105,7 @@ Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, const KeyManag
// Combine sources and seed // Combine sources and seed
for (auto& source : sd_key_sources) { for (auto& source : sd_key_sources) {
for (size_t i = 0; i < source.size(); ++i) for (std::size_t i = 0; i < source.size(); ++i)
source[i] ^= sd_seed[i & 0xF]; source[i] ^= sd_seed[i & 0xF];
} }
@ -207,7 +207,7 @@ Key256 KeyManager::GetKey(S256KeyType id, u64 field1, u64 field2) const {
return s256_keys.at({id, field1, field2}); return s256_keys.at({id, field1, field2});
} }
template <size_t Size> template <std::size_t Size>
void KeyManager::WriteKeyToFile(bool title_key, std::string_view keyname, void KeyManager::WriteKeyToFile(bool title_key, std::string_view keyname,
const std::array<u8, Size>& key) { const std::array<u8, Size>& key) {
const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir); const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir);

View file

@ -108,7 +108,7 @@ private:
void LoadFromFile(const std::string& filename, bool is_title_keys); void LoadFromFile(const std::string& filename, bool is_title_keys);
void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2, void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2,
const std::string& filename, bool title); const std::string& filename, bool title);
template <size_t Size> template <std::size_t Size>
void WriteKeyToFile(bool title_key, std::string_view keyname, const std::array<u8, Size>& key); void WriteKeyToFile(bool title_key, std::string_view keyname, const std::array<u8, Size>& key);
static const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> s128_file_id; static const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> s128_file_id;

View file

@ -14,7 +14,7 @@ constexpr u64 XTS_SECTOR_SIZE = 0x4000;
XTSEncryptionLayer::XTSEncryptionLayer(FileSys::VirtualFile base_, Key256 key_) XTSEncryptionLayer::XTSEncryptionLayer(FileSys::VirtualFile base_, Key256 key_)
: EncryptionLayer(std::move(base_)), cipher(key_, Mode::XTS) {} : EncryptionLayer(std::move(base_)), cipher(key_, Mode::XTS) {}
size_t XTSEncryptionLayer::Read(u8* data, size_t length, size_t offset) const { std::size_t XTSEncryptionLayer::Read(u8* data, std::size_t length, std::size_t offset) const {
if (length == 0) if (length == 0)
return 0; return 0;
@ -46,7 +46,7 @@ size_t XTSEncryptionLayer::Read(u8* data, size_t length, size_t offset) const {
block.resize(XTS_SECTOR_SIZE); block.resize(XTS_SECTOR_SIZE);
cipher.XTSTranscode(block.data(), block.size(), block.data(), cipher.XTSTranscode(block.data(), block.size(), block.data(),
(offset - sector_offset) / XTS_SECTOR_SIZE, XTS_SECTOR_SIZE, Op::Decrypt); (offset - sector_offset) / XTS_SECTOR_SIZE, XTS_SECTOR_SIZE, Op::Decrypt);
const size_t read = XTS_SECTOR_SIZE - sector_offset; const std::size_t read = XTS_SECTOR_SIZE - sector_offset;
if (length + sector_offset < XTS_SECTOR_SIZE) { if (length + sector_offset < XTS_SECTOR_SIZE) {
std::memcpy(data, block.data() + sector_offset, std::min<u64>(length, read)); std::memcpy(data, block.data() + sector_offset, std::min<u64>(length, read));

View file

@ -15,7 +15,7 @@ class XTSEncryptionLayer : public EncryptionLayer {
public: public:
XTSEncryptionLayer(FileSys::VirtualFile base, Key256 key); XTSEncryptionLayer(FileSys::VirtualFile base, Key256 key);
size_t Read(u8* data, size_t length, size_t offset) const override; std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
private: private:
// Must be mutable as operations modify cipher contexts. // Must be mutable as operations modify cipher contexts.

View file

@ -41,13 +41,14 @@ XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) {
for (XCIPartition partition : for (XCIPartition partition :
{XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) { {XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) {
auto raw = main_hfs.GetFile(partition_names[static_cast<size_t>(partition)]); auto raw = main_hfs.GetFile(partition_names[static_cast<std::size_t>(partition)]);
if (raw != nullptr) if (raw != nullptr)
partitions[static_cast<size_t>(partition)] = std::make_shared<PartitionFilesystem>(raw); partitions[static_cast<std::size_t>(partition)] =
std::make_shared<PartitionFilesystem>(raw);
} }
secure_partition = std::make_shared<NSP>( secure_partition = std::make_shared<NSP>(
main_hfs.GetFile(partition_names[static_cast<size_t>(XCIPartition::Secure)])); main_hfs.GetFile(partition_names[static_cast<std::size_t>(XCIPartition::Secure)]));
const auto secure_ncas = secure_partition->GetNCAsCollapsed(); const auto secure_ncas = secure_partition->GetNCAsCollapsed();
std::copy(secure_ncas.begin(), secure_ncas.end(), std::back_inserter(ncas)); std::copy(secure_ncas.begin(), secure_ncas.end(), std::back_inserter(ncas));
@ -92,7 +93,7 @@ Loader::ResultStatus XCI::GetProgramNCAStatus() const {
} }
VirtualDir XCI::GetPartition(XCIPartition partition) const { VirtualDir XCI::GetPartition(XCIPartition partition) const {
return partitions[static_cast<size_t>(partition)]; return partitions[static_cast<std::size_t>(partition)];
} }
std::shared_ptr<NSP> XCI::GetSecurePartitionNSP() const { std::shared_ptr<NSP> XCI::GetSecurePartitionNSP() const {
@ -168,11 +169,11 @@ bool XCI::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
} }
Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) {
if (partitions[static_cast<size_t>(part)] == nullptr) { if (partitions[static_cast<std::size_t>(part)] == nullptr) {
return Loader::ResultStatus::ErrorXCIMissingPartition; return Loader::ResultStatus::ErrorXCIMissingPartition;
} }
for (const VirtualFile& file : partitions[static_cast<size_t>(part)]->GetFiles()) { for (const VirtualFile& file : partitions[static_cast<std::size_t>(part)]->GetFiles()) {
if (file->GetExtension() != "nca") if (file->GetExtension() != "nca")
continue; continue;
auto nca = std::make_shared<NCA>(file); auto nca = std::make_shared<NCA>(file);
@ -187,7 +188,7 @@ Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) {
} else { } else {
const u16 error_id = static_cast<u16>(nca->GetStatus()); const u16 error_id = static_cast<u16>(nca->GetStatus());
LOG_CRITICAL(Loader, "Could not load NCA {}/{}, failed with error code {:04X} ({})", LOG_CRITICAL(Loader, "Could not load NCA {}/{}, failed with error code {:04X} ({})",
partition_names[static_cast<size_t>(part)], nca->GetName(), error_id, partition_names[static_cast<std::size_t>(part)], nca->GetName(), error_id,
nca->GetStatus()); nca->GetStatus());
} }
} }

View file

@ -298,11 +298,11 @@ NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_, u64 bktr_base_ivfc_off
auto section = sections[i]; auto section = sections[i];
if (section.raw.header.filesystem_type == NCASectionFilesystemType::ROMFS) { if (section.raw.header.filesystem_type == NCASectionFilesystemType::ROMFS) {
const size_t base_offset = const std::size_t base_offset =
header.section_tables[i].media_offset * MEDIA_OFFSET_MULTIPLIER; header.section_tables[i].media_offset * MEDIA_OFFSET_MULTIPLIER;
ivfc_offset = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].offset; ivfc_offset = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].offset;
const size_t romfs_offset = base_offset + ivfc_offset; const std::size_t romfs_offset = base_offset + ivfc_offset;
const size_t romfs_size = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].size; const std::size_t romfs_size = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].size;
auto raw = std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset); auto raw = std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset);
auto dec = Decrypt(section, raw, romfs_offset); auto dec = Decrypt(section, raw, romfs_offset);

View file

@ -25,7 +25,7 @@ enum EntryType : u8 {
struct Entry { struct Entry {
Entry(std::string_view view, EntryType entry_type, u64 entry_size) Entry(std::string_view view, EntryType entry_type, u64 entry_size)
: type{entry_type}, file_size{entry_size} { : type{entry_type}, file_size{entry_size} {
const size_t copy_size = view.copy(filename, std::size(filename) - 1); const std::size_t copy_size = view.copy(filename, std::size(filename) - 1);
filename[copy_size] = '\0'; filename[copy_size] = '\0';
} }

View file

@ -11,11 +11,11 @@
namespace FileSys { namespace FileSys {
bool operator>=(TitleType lhs, TitleType rhs) { bool operator>=(TitleType lhs, TitleType rhs) {
return static_cast<size_t>(lhs) >= static_cast<size_t>(rhs); return static_cast<std::size_t>(lhs) >= static_cast<std::size_t>(rhs);
} }
bool operator<=(TitleType lhs, TitleType rhs) { bool operator<=(TitleType lhs, TitleType rhs) {
return static_cast<size_t>(lhs) <= static_cast<size_t>(rhs); return static_cast<std::size_t>(lhs) <= static_cast<std::size_t>(rhs);
} }
CNMT::CNMT(VirtualFile file) { CNMT::CNMT(VirtualFile file) {

View file

@ -22,11 +22,11 @@ BKTR::BKTR(VirtualFile base_romfs_, VirtualFile bktr_romfs_, RelocationBlock rel
base_romfs(std::move(base_romfs_)), bktr_romfs(std::move(bktr_romfs_)), base_romfs(std::move(base_romfs_)), bktr_romfs(std::move(bktr_romfs_)),
encrypted(is_encrypted_), key(key_), base_offset(base_offset_), ivfc_offset(ivfc_offset_), encrypted(is_encrypted_), key(key_), base_offset(base_offset_), ivfc_offset(ivfc_offset_),
section_ctr(section_ctr_) { section_ctr(section_ctr_) {
for (size_t i = 0; i < relocation.number_buckets - 1; ++i) { for (std::size_t i = 0; i < relocation.number_buckets - 1; ++i) {
relocation_buckets[i].entries.push_back({relocation.base_offsets[i + 1], 0, 0}); relocation_buckets[i].entries.push_back({relocation.base_offsets[i + 1], 0, 0});
} }
for (size_t i = 0; i < subsection.number_buckets - 1; ++i) { for (std::size_t i = 0; i < subsection.number_buckets - 1; ++i) {
subsection_buckets[i].entries.push_back({subsection_buckets[i + 1].entries[0].address_patch, subsection_buckets[i].entries.push_back({subsection_buckets[i + 1].entries[0].address_patch,
{0}, {0},
subsection_buckets[i + 1].entries[0].ctr}); subsection_buckets[i + 1].entries[0].ctr});
@ -37,7 +37,7 @@ BKTR::BKTR(VirtualFile base_romfs_, VirtualFile bktr_romfs_, RelocationBlock rel
BKTR::~BKTR() = default; BKTR::~BKTR() = default;
size_t BKTR::Read(u8* data, size_t length, size_t offset) const { std::size_t BKTR::Read(u8* data, std::size_t length, std::size_t offset) const {
// Read out of bounds. // Read out of bounds.
if (offset >= relocation.size) if (offset >= relocation.size)
return 0; return 0;
@ -69,14 +69,14 @@ size_t BKTR::Read(u8* data, size_t length, size_t offset) const {
std::vector<u8> iv(16); std::vector<u8> iv(16);
auto subsection_ctr = subsection.ctr; auto subsection_ctr = subsection.ctr;
auto offset_iv = section_offset + base_offset; auto offset_iv = section_offset + base_offset;
for (size_t i = 0; i < section_ctr.size(); ++i) for (std::size_t i = 0; i < section_ctr.size(); ++i)
iv[i] = section_ctr[0x8 - i - 1]; iv[i] = section_ctr[0x8 - i - 1];
offset_iv >>= 4; offset_iv >>= 4;
for (size_t i = 0; i < sizeof(u64); ++i) { for (std::size_t i = 0; i < sizeof(u64); ++i) {
iv[0xF - i] = static_cast<u8>(offset_iv & 0xFF); iv[0xF - i] = static_cast<u8>(offset_iv & 0xFF);
offset_iv >>= 8; offset_iv >>= 8;
} }
for (size_t i = 0; i < sizeof(u32); ++i) { for (std::size_t i = 0; i < sizeof(u32); ++i) {
iv[0x7 - i] = static_cast<u8>(subsection_ctr & 0xFF); iv[0x7 - i] = static_cast<u8>(subsection_ctr & 0xFF);
subsection_ctr >>= 8; subsection_ctr >>= 8;
} }
@ -110,7 +110,7 @@ size_t BKTR::Read(u8* data, size_t length, size_t offset) const {
} }
template <bool Subsection, typename BlockType, typename BucketType> template <bool Subsection, typename BlockType, typename BucketType>
std::pair<size_t, size_t> BKTR::SearchBucketEntry(u64 offset, BlockType block, std::pair<std::size_t, std::size_t> BKTR::SearchBucketEntry(u64 offset, BlockType block,
BucketType buckets) const { BucketType buckets) const {
if constexpr (Subsection) { if constexpr (Subsection) {
const auto last_bucket = buckets[block.number_buckets - 1]; const auto last_bucket = buckets[block.number_buckets - 1];
@ -120,8 +120,8 @@ std::pair<size_t, size_t> BKTR::SearchBucketEntry(u64 offset, BlockType block,
ASSERT_MSG(offset <= block.size, "Offset is out of bounds in BKTR relocation block."); ASSERT_MSG(offset <= block.size, "Offset is out of bounds in BKTR relocation block.");
} }
size_t bucket_id = std::count_if(block.base_offsets.begin() + 1, std::size_t bucket_id = std::count_if(
block.base_offsets.begin() + block.number_buckets, block.base_offsets.begin() + 1, block.base_offsets.begin() + block.number_buckets,
[&offset](u64 base_offset) { return base_offset <= offset; }); [&offset](u64 base_offset) { return base_offset <= offset; });
const auto bucket = buckets[bucket_id]; const auto bucket = buckets[bucket_id];
@ -129,9 +129,9 @@ std::pair<size_t, size_t> BKTR::SearchBucketEntry(u64 offset, BlockType block,
if (bucket.number_entries == 1) if (bucket.number_entries == 1)
return {bucket_id, 0}; return {bucket_id, 0};
size_t low = 0; std::size_t low = 0;
size_t mid = 0; std::size_t mid = 0;
size_t high = bucket.number_entries - 1; std::size_t high = bucket.number_entries - 1;
while (low <= high) { while (low <= high) {
mid = (low + high) / 2; mid = (low + high) / 2;
if (bucket.entries[mid].address_patch > offset) { if (bucket.entries[mid].address_patch > offset) {
@ -179,11 +179,11 @@ std::string BKTR::GetName() const {
return base_romfs->GetName(); return base_romfs->GetName();
} }
size_t BKTR::GetSize() const { std::size_t BKTR::GetSize() const {
return relocation.size; return relocation.size;
} }
bool BKTR::Resize(size_t new_size) { bool BKTR::Resize(std::size_t new_size) {
return false; return false;
} }
@ -199,7 +199,7 @@ bool BKTR::IsReadable() const {
return true; return true;
} }
size_t BKTR::Write(const u8* data, size_t length, size_t offset) { std::size_t BKTR::Write(const u8* data, std::size_t length, std::size_t offset) {
return 0; return 0;
} }

View file

@ -98,13 +98,13 @@ public:
Core::Crypto::Key128 key, u64 base_offset, u64 ivfc_offset, std::array<u8, 8> section_ctr); Core::Crypto::Key128 key, u64 base_offset, u64 ivfc_offset, std::array<u8, 8> section_ctr);
~BKTR() override; ~BKTR() override;
size_t Read(u8* data, size_t length, size_t offset) const override; std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
std::string GetName() const override; std::string GetName() const override;
size_t GetSize() const override; std::size_t GetSize() const override;
bool Resize(size_t new_size) override; bool Resize(std::size_t new_size) override;
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override; std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
@ -112,13 +112,13 @@ public:
bool IsReadable() const override; bool IsReadable() const override;
size_t Write(const u8* data, size_t length, size_t offset) override; std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override;
bool Rename(std::string_view name) override; bool Rename(std::string_view name) override;
private: private:
template <bool Subsection, typename BlockType, typename BucketType> template <bool Subsection, typename BlockType, typename BucketType>
std::pair<size_t, size_t> SearchBucketEntry(u64 offset, BlockType block, std::pair<std::size_t, std::size_t> SearchBucketEntry(u64 offset, BlockType block,
BucketType buckets) const; BucketType buckets) const;
RelocationEntry GetRelocationEntry(u64 offset) const; RelocationEntry GetRelocationEntry(u64 offset) const;

View file

@ -42,21 +42,21 @@ PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) {
is_hfs = pfs_header.magic == Common::MakeMagic('H', 'F', 'S', '0'); is_hfs = pfs_header.magic == Common::MakeMagic('H', 'F', 'S', '0');
size_t entry_size = is_hfs ? sizeof(HFSEntry) : sizeof(PFSEntry); std::size_t entry_size = is_hfs ? sizeof(HFSEntry) : sizeof(PFSEntry);
size_t metadata_size = std::size_t metadata_size =
sizeof(Header) + (pfs_header.num_entries * entry_size) + pfs_header.strtab_size; sizeof(Header) + (pfs_header.num_entries * entry_size) + pfs_header.strtab_size;
// Actually read in now... // Actually read in now...
std::vector<u8> file_data = file->ReadBytes(metadata_size); std::vector<u8> file_data = file->ReadBytes(metadata_size);
const size_t total_size = file_data.size(); const std::size_t total_size = file_data.size();
if (total_size != metadata_size) { if (total_size != metadata_size) {
status = Loader::ResultStatus::ErrorIncorrectPFSFileSize; status = Loader::ResultStatus::ErrorIncorrectPFSFileSize;
return; return;
} }
size_t entries_offset = sizeof(Header); std::size_t entries_offset = sizeof(Header);
size_t strtab_offset = entries_offset + (pfs_header.num_entries * entry_size); std::size_t strtab_offset = entries_offset + (pfs_header.num_entries * entry_size);
content_offset = strtab_offset + pfs_header.strtab_size; content_offset = strtab_offset + pfs_header.strtab_size;
for (u16 i = 0; i < pfs_header.num_entries; i++) { for (u16 i = 0; i < pfs_header.num_entries; i++) {
FSEntry entry; FSEntry entry;

View file

@ -79,7 +79,7 @@ private:
Header pfs_header{}; Header pfs_header{};
bool is_hfs = false; bool is_hfs = false;
size_t content_offset = 0; std::size_t content_offset = 0;
std::vector<VirtualFile> pfs_files; std::vector<VirtualFile> pfs_files;
std::vector<VirtualDir> pfs_dirs; std::vector<VirtualDir> pfs_dirs;

View file

@ -21,7 +21,7 @@ constexpr u64 SINGLE_BYTE_MODULUS = 0x100;
std::string FormatTitleVersion(u32 version, TitleVersionFormat format) { std::string FormatTitleVersion(u32 version, TitleVersionFormat format) {
std::array<u8, sizeof(u32)> bytes{}; std::array<u8, sizeof(u32)> bytes{};
bytes[0] = version % SINGLE_BYTE_MODULUS; bytes[0] = version % SINGLE_BYTE_MODULUS;
for (size_t i = 1; i < bytes.size(); ++i) { for (std::size_t i = 1; i < bytes.size(); ++i) {
version /= SINGLE_BYTE_MODULUS; version /= SINGLE_BYTE_MODULUS;
bytes[i] = version % SINGLE_BYTE_MODULUS; bytes[i] = version % SINGLE_BYTE_MODULUS;
} }
@ -36,7 +36,7 @@ constexpr std::array<const char*, 1> PATCH_TYPE_NAMES{
}; };
std::string FormatPatchTypeName(PatchType type) { std::string FormatPatchTypeName(PatchType type) {
return PATCH_TYPE_NAMES.at(static_cast<size_t>(type)); return PATCH_TYPE_NAMES.at(static_cast<std::size_t>(type));
} }
PatchManager::PatchManager(u64 title_id) : title_id(title_id) {} PatchManager::PatchManager(u64 title_id) : title_id(title_id) {}

View file

@ -13,7 +13,7 @@
namespace FileSys { namespace FileSys {
Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) {
size_t total_size = static_cast<size_t>(file->GetSize()); std::size_t total_size = static_cast<std::size_t>(file->GetSize());
if (total_size < sizeof(Header)) if (total_size < sizeof(Header))
return Loader::ResultStatus::ErrorBadNPDMHeader; return Loader::ResultStatus::ErrorBadNPDMHeader;

View file

@ -62,11 +62,11 @@ static std::string GetCNMTName(TitleType type, u64 title_id) {
"" ///< Currently unknown 'DeltaTitle' "" ///< Currently unknown 'DeltaTitle'
}; };
auto index = static_cast<size_t>(type); auto index = static_cast<std::size_t>(type);
// If the index is after the jump in TitleType, subtract it out. // If the index is after the jump in TitleType, subtract it out.
if (index >= static_cast<size_t>(TitleType::Application)) { if (index >= static_cast<std::size_t>(TitleType::Application)) {
index -= static_cast<size_t>(TitleType::Application) - index -= static_cast<std::size_t>(TitleType::Application) -
static_cast<size_t>(TitleType::FirmwarePackageB); static_cast<std::size_t>(TitleType::FirmwarePackageB);
} }
return fmt::format("{}_{:016x}.cnmt", TITLE_TYPE_NAMES[index], title_id); return fmt::format("{}_{:016x}.cnmt", TITLE_TYPE_NAMES[index], title_id);
} }
@ -105,7 +105,7 @@ VirtualFile RegisteredCache::OpenFileOrDirectoryConcat(const VirtualDir& dir,
} else { } else {
std::vector<VirtualFile> concat; std::vector<VirtualFile> concat;
// Since the files are a two-digit hex number, max is FF. // Since the files are a two-digit hex number, max is FF.
for (size_t i = 0; i < 0x100; ++i) { for (std::size_t i = 0; i < 0x100; ++i) {
auto next = nca_dir->GetFile(fmt::format("{:02X}", i)); auto next = nca_dir->GetFile(fmt::format("{:02X}", i));
if (next != nullptr) { if (next != nullptr) {
concat.push_back(std::move(next)); concat.push_back(std::move(next));

View file

@ -49,7 +49,7 @@ struct FileEntry {
static_assert(sizeof(FileEntry) == 0x20, "FileEntry has incorrect size."); static_assert(sizeof(FileEntry) == 0x20, "FileEntry has incorrect size.");
template <typename Entry> template <typename Entry>
static std::pair<Entry, std::string> GetEntry(const VirtualFile& file, size_t offset) { static std::pair<Entry, std::string> GetEntry(const VirtualFile& file, std::size_t offset) {
Entry entry{}; Entry entry{};
if (file->ReadObject(&entry, offset) != sizeof(Entry)) if (file->ReadObject(&entry, offset) != sizeof(Entry))
return {}; return {};
@ -59,8 +59,8 @@ static std::pair<Entry, std::string> GetEntry(const VirtualFile& file, size_t of
return {entry, string}; return {entry, string};
} }
void ProcessFile(VirtualFile file, size_t file_offset, size_t data_offset, u32 this_file_offset, void ProcessFile(VirtualFile file, std::size_t file_offset, std::size_t data_offset,
std::shared_ptr<VectorVfsDirectory> parent) { u32 this_file_offset, std::shared_ptr<VectorVfsDirectory> parent) {
while (true) { while (true) {
auto entry = GetEntry<FileEntry>(file, file_offset + this_file_offset); auto entry = GetEntry<FileEntry>(file, file_offset + this_file_offset);
@ -74,8 +74,9 @@ void ProcessFile(VirtualFile file, size_t file_offset, size_t data_offset, u32 t
} }
} }
void ProcessDirectory(VirtualFile file, size_t dir_offset, size_t file_offset, size_t data_offset, void ProcessDirectory(VirtualFile file, std::size_t dir_offset, std::size_t file_offset,
u32 this_dir_offset, std::shared_ptr<VectorVfsDirectory> parent) { std::size_t data_offset, u32 this_dir_offset,
std::shared_ptr<VectorVfsDirectory> parent) {
while (true) { while (true) {
auto entry = GetEntry<DirectoryEntry>(file, dir_offset + this_dir_offset); auto entry = GetEntry<DirectoryEntry>(file, dir_offset + this_dir_offset);
auto current = std::make_shared<VectorVfsDirectory>( auto current = std::make_shared<VectorVfsDirectory>(

View file

@ -167,18 +167,18 @@ std::string VfsFile::GetExtension() const {
VfsDirectory::~VfsDirectory() = default; VfsDirectory::~VfsDirectory() = default;
boost::optional<u8> VfsFile::ReadByte(size_t offset) const { boost::optional<u8> VfsFile::ReadByte(std::size_t offset) const {
u8 out{}; u8 out{};
size_t size = Read(&out, 1, offset); std::size_t size = Read(&out, 1, offset);
if (size == 1) if (size == 1)
return out; return out;
return boost::none; return boost::none;
} }
std::vector<u8> VfsFile::ReadBytes(size_t size, size_t offset) const { std::vector<u8> VfsFile::ReadBytes(std::size_t size, std::size_t offset) const {
std::vector<u8> out(size); std::vector<u8> out(size);
size_t read_size = Read(out.data(), size, offset); std::size_t read_size = Read(out.data(), size, offset);
out.resize(read_size); out.resize(read_size);
return out; return out;
} }
@ -187,11 +187,11 @@ std::vector<u8> VfsFile::ReadAllBytes() const {
return ReadBytes(GetSize()); return ReadBytes(GetSize());
} }
bool VfsFile::WriteByte(u8 data, size_t offset) { bool VfsFile::WriteByte(u8 data, std::size_t offset) {
return Write(&data, 1, offset) == 1; return Write(&data, 1, offset) == 1;
} }
size_t VfsFile::WriteBytes(const std::vector<u8>& data, size_t offset) { std::size_t VfsFile::WriteBytes(const std::vector<u8>& data, std::size_t offset) {
return Write(data.data(), data.size(), offset); return Write(data.data(), data.size(), offset);
} }
@ -215,7 +215,7 @@ std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(std::string_view path) co
} }
auto dir = GetSubdirectory(vec[0]); auto dir = GetSubdirectory(vec[0]);
for (size_t component = 1; component < vec.size() - 1; ++component) { for (std::size_t component = 1; component < vec.size() - 1; ++component) {
if (dir == nullptr) { if (dir == nullptr) {
return nullptr; return nullptr;
} }
@ -249,7 +249,7 @@ std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryRelative(std::string_vie
} }
auto dir = GetSubdirectory(vec[0]); auto dir = GetSubdirectory(vec[0]);
for (size_t component = 1; component < vec.size(); ++component) { for (std::size_t component = 1; component < vec.size(); ++component) {
if (dir == nullptr) { if (dir == nullptr) {
return nullptr; return nullptr;
} }
@ -286,7 +286,7 @@ bool VfsDirectory::IsRoot() const {
return GetParentDirectory() == nullptr; return GetParentDirectory() == nullptr;
} }
size_t VfsDirectory::GetSize() const { std::size_t VfsDirectory::GetSize() const {
const auto& files = GetFiles(); const auto& files = GetFiles();
const auto sum_sizes = [](const auto& range) { const auto sum_sizes = [](const auto& range) {
return std::accumulate(range.begin(), range.end(), 0ULL, return std::accumulate(range.begin(), range.end(), 0ULL,
@ -434,13 +434,13 @@ bool ReadOnlyVfsDirectory::Rename(std::string_view name) {
return false; return false;
} }
bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, size_t block_size) { bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, std::size_t block_size) {
if (file1->GetSize() != file2->GetSize()) if (file1->GetSize() != file2->GetSize())
return false; return false;
std::vector<u8> f1_v(block_size); std::vector<u8> f1_v(block_size);
std::vector<u8> f2_v(block_size); std::vector<u8> f2_v(block_size);
for (size_t i = 0; i < file1->GetSize(); i += block_size) { for (std::size_t i = 0; i < file1->GetSize(); i += block_size) {
auto f1_vs = file1->Read(f1_v.data(), block_size, i); auto f1_vs = file1->Read(f1_v.data(), block_size, i);
auto f2_vs = file2->Read(f2_v.data(), block_size, i); auto f2_vs = file2->Read(f2_v.data(), block_size, i);

View file

@ -92,9 +92,9 @@ public:
// Retrieves the extension of the file name. // Retrieves the extension of the file name.
virtual std::string GetExtension() const; virtual std::string GetExtension() const;
// Retrieves the size of the file. // Retrieves the size of the file.
virtual size_t GetSize() const = 0; virtual std::size_t GetSize() const = 0;
// Resizes the file to new_size. Returns whether or not the operation was successful. // Resizes the file to new_size. Returns whether or not the operation was successful.
virtual bool Resize(size_t new_size) = 0; virtual bool Resize(std::size_t new_size) = 0;
// Gets a pointer to the directory containing this file, returning nullptr if there is none. // Gets a pointer to the directory containing this file, returning nullptr if there is none.
virtual std::shared_ptr<VfsDirectory> GetContainingDirectory() const = 0; virtual std::shared_ptr<VfsDirectory> GetContainingDirectory() const = 0;
@ -105,15 +105,15 @@ public:
// The primary method of reading from the file. Reads length bytes into data starting at offset // The primary method of reading from the file. Reads length bytes into data starting at offset
// into file. Returns number of bytes successfully read. // into file. Returns number of bytes successfully read.
virtual size_t Read(u8* data, size_t length, size_t offset = 0) const = 0; virtual std::size_t Read(u8* data, std::size_t length, std::size_t offset = 0) const = 0;
// The primary method of writing to the file. Writes length bytes from data starting at offset // The primary method of writing to the file. Writes length bytes from data starting at offset
// into file. Returns number of bytes successfully written. // into file. Returns number of bytes successfully written.
virtual size_t Write(const u8* data, size_t length, size_t offset = 0) = 0; virtual std::size_t Write(const u8* data, std::size_t length, std::size_t offset = 0) = 0;
// Reads exactly one byte at the offset provided, returning boost::none on error. // Reads exactly one byte at the offset provided, returning boost::none on error.
virtual boost::optional<u8> ReadByte(size_t offset = 0) const; virtual boost::optional<u8> ReadByte(std::size_t offset = 0) const;
// Reads size bytes starting at offset in file into a vector. // Reads size bytes starting at offset in file into a vector.
virtual std::vector<u8> ReadBytes(size_t size, size_t offset = 0) const; virtual std::vector<u8> ReadBytes(std::size_t size, std::size_t offset = 0) const;
// Reads all the bytes from the file into a vector. Equivalent to 'file->Read(file->GetSize(), // Reads all the bytes from the file into a vector. Equivalent to 'file->Read(file->GetSize(),
// 0)' // 0)'
virtual std::vector<u8> ReadAllBytes() const; virtual std::vector<u8> ReadAllBytes() const;
@ -121,7 +121,7 @@ public:
// Reads an array of type T, size number_elements starting at offset. // Reads an array of type T, size number_elements starting at offset.
// Returns the number of bytes (sizeof(T)*number_elements) read successfully. // Returns the number of bytes (sizeof(T)*number_elements) read successfully.
template <typename T> template <typename T>
size_t ReadArray(T* data, size_t number_elements, size_t offset = 0) const { std::size_t ReadArray(T* data, std::size_t number_elements, std::size_t offset = 0) const {
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
return Read(reinterpret_cast<u8*>(data), number_elements * sizeof(T), offset); return Read(reinterpret_cast<u8*>(data), number_elements * sizeof(T), offset);
@ -130,7 +130,7 @@ public:
// Reads size bytes into the memory starting at data starting at offset into the file. // Reads size bytes into the memory starting at data starting at offset into the file.
// Returns the number of bytes read successfully. // Returns the number of bytes read successfully.
template <typename T> template <typename T>
size_t ReadBytes(T* data, size_t size, size_t offset = 0) const { std::size_t ReadBytes(T* data, std::size_t size, std::size_t offset = 0) const {
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
return Read(reinterpret_cast<u8*>(data), size, offset); return Read(reinterpret_cast<u8*>(data), size, offset);
} }
@ -138,22 +138,22 @@ public:
// Reads one object of type T starting at offset in file. // Reads one object of type T starting at offset in file.
// Returns the number of bytes read successfully (sizeof(T)). // Returns the number of bytes read successfully (sizeof(T)).
template <typename T> template <typename T>
size_t ReadObject(T* data, size_t offset = 0) const { std::size_t ReadObject(T* data, std::size_t offset = 0) const {
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
return Read(reinterpret_cast<u8*>(data), sizeof(T), offset); return Read(reinterpret_cast<u8*>(data), sizeof(T), offset);
} }
// Writes exactly one byte to offset in file and retuns whether or not the byte was written // Writes exactly one byte to offset in file and retuns whether or not the byte was written
// successfully. // successfully.
virtual bool WriteByte(u8 data, size_t offset = 0); virtual bool WriteByte(u8 data, std::size_t offset = 0);
// Writes a vector of bytes to offset in file and returns the number of bytes successfully // Writes a vector of bytes to offset in file and returns the number of bytes successfully
// written. // written.
virtual size_t WriteBytes(const std::vector<u8>& data, size_t offset = 0); virtual std::size_t WriteBytes(const std::vector<u8>& data, std::size_t offset = 0);
// Writes an array of type T, size number_elements to offset in file. // Writes an array of type T, size number_elements to offset in file.
// Returns the number of bytes (sizeof(T)*number_elements) written successfully. // Returns the number of bytes (sizeof(T)*number_elements) written successfully.
template <typename T> template <typename T>
size_t WriteArray(const T* data, size_t number_elements, size_t offset = 0) { std::size_t WriteArray(const T* data, std::size_t number_elements, std::size_t offset = 0) {
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
return Write(data, number_elements * sizeof(T), offset); return Write(data, number_elements * sizeof(T), offset);
} }
@ -161,7 +161,7 @@ public:
// Writes size bytes starting at memory location data to offset in file. // Writes size bytes starting at memory location data to offset in file.
// Returns the number of bytes written successfully. // Returns the number of bytes written successfully.
template <typename T> template <typename T>
size_t WriteBytes(const T* data, size_t size, size_t offset = 0) { std::size_t WriteBytes(const T* data, std::size_t size, std::size_t offset = 0) {
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
return Write(reinterpret_cast<const u8*>(data), size, offset); return Write(reinterpret_cast<const u8*>(data), size, offset);
} }
@ -169,7 +169,7 @@ public:
// Writes one object of type T to offset in file. // Writes one object of type T to offset in file.
// Returns the number of bytes written successfully (sizeof(T)). // Returns the number of bytes written successfully (sizeof(T)).
template <typename T> template <typename T>
size_t WriteObject(const T& data, size_t offset = 0) { std::size_t WriteObject(const T& data, std::size_t offset = 0) {
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
return Write(&data, sizeof(T), offset); return Write(&data, sizeof(T), offset);
} }
@ -221,7 +221,7 @@ public:
// Returns the name of the directory. // Returns the name of the directory.
virtual std::string GetName() const = 0; virtual std::string GetName() const = 0;
// Returns the total size of all files and subdirectories in this directory. // Returns the total size of all files and subdirectories in this directory.
virtual size_t GetSize() const; virtual std::size_t GetSize() const;
// Returns the parent directory of this directory. Returns nullptr if this directory is root or // Returns the parent directory of this directory. Returns nullptr if this directory is root or
// has no parent. // has no parent.
virtual std::shared_ptr<VfsDirectory> GetParentDirectory() const = 0; virtual std::shared_ptr<VfsDirectory> GetParentDirectory() const = 0;
@ -311,7 +311,7 @@ public:
}; };
// Compare the two files, byte-for-byte, in increments specificed by block_size // Compare the two files, byte-for-byte, in increments specificed by block_size
bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, size_t block_size = 0x200); bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, std::size_t block_size = 0x200);
// A method that copies the raw data between two different implementations of VirtualFile. If you // A method that copies the raw data between two different implementations of VirtualFile. If you
// are using the same implementation, it is probably better to use the Copy method in the parent // are using the same implementation, it is probably better to use the Copy method in the parent

View file

@ -20,7 +20,7 @@ VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string name) {
ConcatenatedVfsFile::ConcatenatedVfsFile(std::vector<VirtualFile> files_, std::string name) ConcatenatedVfsFile::ConcatenatedVfsFile(std::vector<VirtualFile> files_, std::string name)
: name(std::move(name)) { : name(std::move(name)) {
size_t next_offset = 0; std::size_t next_offset = 0;
for (const auto& file : files_) { for (const auto& file : files_) {
files[next_offset] = file; files[next_offset] = file;
next_offset += file->GetSize(); next_offset += file->GetSize();
@ -35,13 +35,13 @@ std::string ConcatenatedVfsFile::GetName() const {
return files.begin()->second->GetName(); return files.begin()->second->GetName();
} }
size_t ConcatenatedVfsFile::GetSize() const { std::size_t ConcatenatedVfsFile::GetSize() const {
if (files.empty()) if (files.empty())
return 0; return 0;
return files.rbegin()->first + files.rbegin()->second->GetSize(); return files.rbegin()->first + files.rbegin()->second->GetSize();
} }
bool ConcatenatedVfsFile::Resize(size_t new_size) { bool ConcatenatedVfsFile::Resize(std::size_t new_size) {
return false; return false;
} }
@ -59,7 +59,7 @@ bool ConcatenatedVfsFile::IsReadable() const {
return true; return true;
} }
size_t ConcatenatedVfsFile::Read(u8* data, size_t length, size_t offset) const { std::size_t ConcatenatedVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const {
auto entry = files.end(); auto entry = files.end();
for (auto iter = files.begin(); iter != files.end(); ++iter) { for (auto iter = files.begin(); iter != files.end(); ++iter) {
if (iter->first > offset) { if (iter->first > offset) {
@ -84,7 +84,7 @@ size_t ConcatenatedVfsFile::Read(u8* data, size_t length, size_t offset) const {
return entry->second->Read(data, length, offset - entry->first); return entry->second->Read(data, length, offset - entry->first);
} }
size_t ConcatenatedVfsFile::Write(const u8* data, size_t length, size_t offset) { std::size_t ConcatenatedVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) {
return 0; return 0;
} }

View file

@ -23,13 +23,13 @@ class ConcatenatedVfsFile : public VfsFile {
public: public:
std::string GetName() const override; std::string GetName() const override;
size_t GetSize() const override; std::size_t GetSize() const override;
bool Resize(size_t new_size) override; bool Resize(std::size_t new_size) override;
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override; std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
bool IsWritable() const override; bool IsWritable() const override;
bool IsReadable() const override; bool IsReadable() const override;
size_t Read(u8* data, size_t length, size_t offset) const override; std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
size_t Write(const u8* data, size_t length, size_t offset) override; std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override;
bool Rename(std::string_view name) override; bool Rename(std::string_view name) override;
private: private:

View file

@ -9,7 +9,7 @@
namespace FileSys { namespace FileSys {
OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, size_t size_, size_t offset_, OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, std::size_t size_, std::size_t offset_,
std::string name_, VirtualDir parent_) std::string name_, VirtualDir parent_)
: file(file_), offset(offset_), size(size_), name(std::move(name_)), : file(file_), offset(offset_), size(size_), name(std::move(name_)),
parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {} parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {}
@ -18,11 +18,11 @@ std::string OffsetVfsFile::GetName() const {
return name.empty() ? file->GetName() : name; return name.empty() ? file->GetName() : name;
} }
size_t OffsetVfsFile::GetSize() const { std::size_t OffsetVfsFile::GetSize() const {
return size; return size;
} }
bool OffsetVfsFile::Resize(size_t new_size) { bool OffsetVfsFile::Resize(std::size_t new_size) {
if (offset + new_size < file->GetSize()) { if (offset + new_size < file->GetSize()) {
size = new_size; size = new_size;
} else { } else {
@ -47,22 +47,22 @@ bool OffsetVfsFile::IsReadable() const {
return file->IsReadable(); return file->IsReadable();
} }
size_t OffsetVfsFile::Read(u8* data, size_t length, size_t r_offset) const { std::size_t OffsetVfsFile::Read(u8* data, std::size_t length, std::size_t r_offset) const {
return file->Read(data, TrimToFit(length, r_offset), offset + r_offset); return file->Read(data, TrimToFit(length, r_offset), offset + r_offset);
} }
size_t OffsetVfsFile::Write(const u8* data, size_t length, size_t r_offset) { std::size_t OffsetVfsFile::Write(const u8* data, std::size_t length, std::size_t r_offset) {
return file->Write(data, TrimToFit(length, r_offset), offset + r_offset); return file->Write(data, TrimToFit(length, r_offset), offset + r_offset);
} }
boost::optional<u8> OffsetVfsFile::ReadByte(size_t r_offset) const { boost::optional<u8> OffsetVfsFile::ReadByte(std::size_t r_offset) const {
if (r_offset < size) if (r_offset < size)
return file->ReadByte(offset + r_offset); return file->ReadByte(offset + r_offset);
return boost::none; return boost::none;
} }
std::vector<u8> OffsetVfsFile::ReadBytes(size_t r_size, size_t r_offset) const { std::vector<u8> OffsetVfsFile::ReadBytes(std::size_t r_size, std::size_t r_offset) const {
return file->ReadBytes(TrimToFit(r_size, r_offset), offset + r_offset); return file->ReadBytes(TrimToFit(r_size, r_offset), offset + r_offset);
} }
@ -70,14 +70,14 @@ std::vector<u8> OffsetVfsFile::ReadAllBytes() const {
return file->ReadBytes(size, offset); return file->ReadBytes(size, offset);
} }
bool OffsetVfsFile::WriteByte(u8 data, size_t r_offset) { bool OffsetVfsFile::WriteByte(u8 data, std::size_t r_offset) {
if (r_offset < size) if (r_offset < size)
return file->WriteByte(data, offset + r_offset); return file->WriteByte(data, offset + r_offset);
return false; return false;
} }
size_t OffsetVfsFile::WriteBytes(const std::vector<u8>& data, size_t r_offset) { std::size_t OffsetVfsFile::WriteBytes(const std::vector<u8>& data, std::size_t r_offset) {
return file->Write(data.data(), TrimToFit(data.size(), r_offset), offset + r_offset); return file->Write(data.data(), TrimToFit(data.size(), r_offset), offset + r_offset);
} }
@ -85,12 +85,12 @@ bool OffsetVfsFile::Rename(std::string_view name) {
return file->Rename(name); return file->Rename(name);
} }
size_t OffsetVfsFile::GetOffset() const { std::size_t OffsetVfsFile::GetOffset() const {
return offset; return offset;
} }
size_t OffsetVfsFile::TrimToFit(size_t r_size, size_t r_offset) const { std::size_t OffsetVfsFile::TrimToFit(std::size_t r_size, std::size_t r_offset) const {
return std::clamp(r_size, size_t{0}, size - r_offset); return std::clamp(r_size, std::size_t{0}, size - r_offset);
} }
} // namespace FileSys } // namespace FileSys

View file

@ -17,33 +17,33 @@ namespace FileSys {
// the size of this wrapper. // the size of this wrapper.
class OffsetVfsFile : public VfsFile { class OffsetVfsFile : public VfsFile {
public: public:
OffsetVfsFile(std::shared_ptr<VfsFile> file, size_t size, size_t offset = 0, OffsetVfsFile(std::shared_ptr<VfsFile> file, std::size_t size, std::size_t offset = 0,
std::string new_name = "", VirtualDir new_parent = nullptr); std::string new_name = "", VirtualDir new_parent = nullptr);
std::string GetName() const override; std::string GetName() const override;
size_t GetSize() const override; std::size_t GetSize() const override;
bool Resize(size_t new_size) override; bool Resize(std::size_t new_size) override;
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override; std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
bool IsWritable() const override; bool IsWritable() const override;
bool IsReadable() const override; bool IsReadable() const override;
size_t Read(u8* data, size_t length, size_t offset) const override; std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
size_t Write(const u8* data, size_t length, size_t offset) override; std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override;
boost::optional<u8> ReadByte(size_t offset) const override; boost::optional<u8> ReadByte(std::size_t offset) const override;
std::vector<u8> ReadBytes(size_t size, size_t offset) const override; std::vector<u8> ReadBytes(std::size_t size, std::size_t offset) const override;
std::vector<u8> ReadAllBytes() const override; std::vector<u8> ReadAllBytes() const override;
bool WriteByte(u8 data, size_t offset) override; bool WriteByte(u8 data, std::size_t offset) override;
size_t WriteBytes(const std::vector<u8>& data, size_t offset) override; std::size_t WriteBytes(const std::vector<u8>& data, std::size_t offset) override;
bool Rename(std::string_view name) override; bool Rename(std::string_view name) override;
size_t GetOffset() const; std::size_t GetOffset() const;
private: private:
size_t TrimToFit(size_t r_size, size_t r_offset) const; std::size_t TrimToFit(std::size_t r_size, std::size_t r_offset) const;
std::shared_ptr<VfsFile> file; std::shared_ptr<VfsFile> file;
size_t offset; std::size_t offset;
size_t size; std::size_t size;
std::string name; std::string name;
VirtualDir parent; VirtualDir parent;
}; };

View file

@ -227,11 +227,11 @@ std::string RealVfsFile::GetName() const {
return path_components.back(); return path_components.back();
} }
size_t RealVfsFile::GetSize() const { std::size_t RealVfsFile::GetSize() const {
return backing->GetSize(); return backing->GetSize();
} }
bool RealVfsFile::Resize(size_t new_size) { bool RealVfsFile::Resize(std::size_t new_size) {
return backing->Resize(new_size); return backing->Resize(new_size);
} }
@ -247,13 +247,13 @@ bool RealVfsFile::IsReadable() const {
return (perms & Mode::ReadWrite) != 0; return (perms & Mode::ReadWrite) != 0;
} }
size_t RealVfsFile::Read(u8* data, size_t length, size_t offset) const { std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const {
if (!backing->Seek(offset, SEEK_SET)) if (!backing->Seek(offset, SEEK_SET))
return 0; return 0;
return backing->ReadBytes(data, length); return backing->ReadBytes(data, length);
} }
size_t RealVfsFile::Write(const u8* data, size_t length, size_t offset) { std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) {
if (!backing->Seek(offset, SEEK_SET)) if (!backing->Seek(offset, SEEK_SET))
return 0; return 0;
return backing->WriteBytes(data, length); return backing->WriteBytes(data, length);

View file

@ -48,13 +48,13 @@ public:
~RealVfsFile() override; ~RealVfsFile() override;
std::string GetName() const override; std::string GetName() const override;
size_t GetSize() const override; std::size_t GetSize() const override;
bool Resize(size_t new_size) override; bool Resize(std::size_t new_size) override;
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override; std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
bool IsWritable() const override; bool IsWritable() const override;
bool IsReadable() const override; bool IsReadable() const override;
size_t Read(u8* data, size_t length, size_t offset) const override; std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
size_t Write(const u8* data, size_t length, size_t offset) override; std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override;
bool Rename(std::string_view name) override; bool Rename(std::string_view name) override;
private: private:

View file

@ -25,8 +25,8 @@ namespace FileSys {
constexpr u64 NAX_HEADER_PADDING_SIZE = 0x4000; constexpr u64 NAX_HEADER_PADDING_SIZE = 0x4000;
template <typename SourceData, typename SourceKey, typename Destination> template <typename SourceData, typename SourceKey, typename Destination>
static bool CalculateHMAC256(Destination* out, const SourceKey* key, size_t key_length, static bool CalculateHMAC256(Destination* out, const SourceKey* key, std::size_t key_length,
const SourceData* data, size_t data_length) { const SourceData* data, std::size_t data_length) {
mbedtls_md_context_t context; mbedtls_md_context_t context;
mbedtls_md_init(&context); mbedtls_md_init(&context);
@ -91,7 +91,7 @@ Loader::ResultStatus NAX::Parse(std::string_view path) {
const auto enc_keys = header->key_area; const auto enc_keys = header->key_area;
size_t i = 0; std::size_t i = 0;
for (; i < sd_keys.size(); ++i) { for (; i < sd_keys.size(); ++i) {
std::array<Core::Crypto::Key128, 2> nax_keys{}; std::array<Core::Crypto::Key128, 2> nax_keys{};
if (!CalculateHMAC256(nax_keys.data(), sd_keys[i].data(), 0x10, std::string(path).c_str(), if (!CalculateHMAC256(nax_keys.data(), sd_keys[i].data(), 0x10, std::string(path).c_str(),
@ -99,7 +99,7 @@ Loader::ResultStatus NAX::Parse(std::string_view path) {
return Loader::ResultStatus::ErrorNAXKeyHMACFailed; return Loader::ResultStatus::ErrorNAXKeyHMACFailed;
} }
for (size_t j = 0; j < nax_keys.size(); ++j) { for (std::size_t j = 0; j < nax_keys.size(); ++j) {
Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(nax_keys[j], Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(nax_keys[j],
Core::Crypto::Mode::ECB); Core::Crypto::Mode::ECB);
cipher.Transcode(enc_keys[j].data(), 0x10, header->key_area[j].data(), cipher.Transcode(enc_keys[j].data(), 0x10, header->key_area[j].data(),

View file

@ -65,9 +65,9 @@ constexpr u32 MSG_WAITALL = 8;
constexpr u32 LR_REGISTER = 30; constexpr u32 LR_REGISTER = 30;
constexpr u32 SP_REGISTER = 31; constexpr u32 SP_REGISTER = 31;
constexpr u32 PC_REGISTER = 32; constexpr u32 PC_REGISTER = 32;
constexpr u32 CPSR_REGISTER = 33; constexpr u32 PSTATE_REGISTER = 33;
constexpr u32 UC_ARM64_REG_Q0 = 34; constexpr u32 UC_ARM64_REG_Q0 = 34;
constexpr u32 FPSCR_REGISTER = 66; constexpr u32 FPCR_REGISTER = 66;
// TODO/WiP - Used while working on support for FPU // TODO/WiP - Used while working on support for FPU
constexpr u32 TODO_DUMMY_REG_997 = 997; constexpr u32 TODO_DUMMY_REG_997 = 997;
@ -116,7 +116,7 @@ constexpr char target_xml[] =
<reg name="pc" bitsize="64" type="code_ptr"/> <reg name="pc" bitsize="64" type="code_ptr"/>
<flags id="cpsr_flags" size="4"> <flags id="pstate_flags" size="4">
<field name="SP" start="0" end="0"/> <field name="SP" start="0" end="0"/>
<field name="" start="1" end="1"/> <field name="" start="1" end="1"/>
<field name="EL" start="2" end="3"/> <field name="EL" start="2" end="3"/>
@ -135,7 +135,7 @@ constexpr char target_xml[] =
<field name="Z" start="30" end="30"/> <field name="Z" start="30" end="30"/>
<field name="N" start="31" end="31"/> <field name="N" start="31" end="31"/>
</flags> </flags>
<reg name="cpsr" bitsize="32" type="cpsr_flags"/> <reg name="pstate" bitsize="32" type="pstate_flags"/>
</feature> </feature>
<feature name="org.gnu.gdb.aarch64.fpu"> <feature name="org.gnu.gdb.aarch64.fpu">
</feature> </feature>
@ -227,10 +227,10 @@ static u64 RegRead(std::size_t id, Kernel::Thread* thread = nullptr) {
return thread->context.sp; return thread->context.sp;
} else if (id == PC_REGISTER) { } else if (id == PC_REGISTER) {
return thread->context.pc; return thread->context.pc;
} else if (id == CPSR_REGISTER) { } else if (id == PSTATE_REGISTER) {
return thread->context.cpsr; return thread->context.pstate;
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) { } else if (id > PSTATE_REGISTER && id < FPCR_REGISTER) {
return thread->context.fpu_registers[id - UC_ARM64_REG_Q0][0]; return thread->context.vector_registers[id - UC_ARM64_REG_Q0][0];
} else { } else {
return 0; return 0;
} }
@ -247,10 +247,10 @@ static void RegWrite(std::size_t id, u64 val, Kernel::Thread* thread = nullptr)
thread->context.sp = val; thread->context.sp = val;
} else if (id == PC_REGISTER) { } else if (id == PC_REGISTER) {
thread->context.pc = val; thread->context.pc = val;
} else if (id == CPSR_REGISTER) { } else if (id == PSTATE_REGISTER) {
thread->context.cpsr = val; thread->context.pstate = val;
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) { } else if (id > PSTATE_REGISTER && id < FPCR_REGISTER) {
thread->context.fpu_registers[id - (CPSR_REGISTER + 1)][0] = val; thread->context.vector_registers[id - (PSTATE_REGISTER + 1)][0] = val;
} }
} }
@ -292,7 +292,7 @@ static u8 NibbleToHex(u8 n) {
* @param src Pointer to array of output hex string characters. * @param src Pointer to array of output hex string characters.
* @param len Length of src array. * @param len Length of src array.
*/ */
static u32 HexToInt(const u8* src, size_t len) { static u32 HexToInt(const u8* src, std::size_t len) {
u32 output = 0; u32 output = 0;
while (len-- > 0) { while (len-- > 0) {
output = (output << 4) | HexCharToValue(src[0]); output = (output << 4) | HexCharToValue(src[0]);
@ -307,7 +307,7 @@ static u32 HexToInt(const u8* src, size_t len) {
* @param src Pointer to array of output hex string characters. * @param src Pointer to array of output hex string characters.
* @param len Length of src array. * @param len Length of src array.
*/ */
static u64 HexToLong(const u8* src, size_t len) { static u64 HexToLong(const u8* src, std::size_t len) {
u64 output = 0; u64 output = 0;
while (len-- > 0) { while (len-- > 0) {
output = (output << 4) | HexCharToValue(src[0]); output = (output << 4) | HexCharToValue(src[0]);
@ -323,7 +323,7 @@ static u64 HexToLong(const u8* src, size_t len) {
* @param src Pointer to array of u8 bytes. * @param src Pointer to array of u8 bytes.
* @param len Length of src array. * @param len Length of src array.
*/ */
static void MemToGdbHex(u8* dest, const u8* src, size_t len) { static void MemToGdbHex(u8* dest, const u8* src, std::size_t len) {
while (len-- > 0) { while (len-- > 0) {
u8 tmp = *src++; u8 tmp = *src++;
*dest++ = NibbleToHex(tmp >> 4); *dest++ = NibbleToHex(tmp >> 4);
@ -338,7 +338,7 @@ static void MemToGdbHex(u8* dest, const u8* src, size_t len) {
* @param src Pointer to array of output hex string characters. * @param src Pointer to array of output hex string characters.
* @param len Length of src array. * @param len Length of src array.
*/ */
static void GdbHexToMem(u8* dest, const u8* src, size_t len) { static void GdbHexToMem(u8* dest, const u8* src, std::size_t len) {
while (len-- > 0) { while (len-- > 0) {
*dest++ = (HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]); *dest++ = (HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]);
src += 2; src += 2;
@ -406,7 +406,7 @@ static u64 GdbHexToLong(const u8* src) {
/// Read a byte from the gdb client. /// Read a byte from the gdb client.
static u8 ReadByte() { static u8 ReadByte() {
u8 c; u8 c;
size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL); std::size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL);
if (received_size != 1) { if (received_size != 1) {
LOG_ERROR(Debug_GDBStub, "recv failed: {}", received_size); LOG_ERROR(Debug_GDBStub, "recv failed: {}", received_size);
Shutdown(); Shutdown();
@ -416,7 +416,7 @@ static u8 ReadByte() {
} }
/// Calculate the checksum of the current command buffer. /// Calculate the checksum of the current command buffer.
static u8 CalculateChecksum(const u8* buffer, size_t length) { static u8 CalculateChecksum(const u8* buffer, std::size_t length) {
return static_cast<u8>(std::accumulate(buffer, buffer + length, 0, std::plus<u8>())); return static_cast<u8>(std::accumulate(buffer, buffer + length, 0, std::plus<u8>()));
} }
@ -518,7 +518,7 @@ bool CheckBreakpoint(VAddr addr, BreakpointType type) {
* @param packet Packet to be sent to client. * @param packet Packet to be sent to client.
*/ */
static void SendPacket(const char packet) { static void SendPacket(const char packet) {
size_t sent_size = send(gdbserver_socket, &packet, 1, 0); std::size_t sent_size = send(gdbserver_socket, &packet, 1, 0);
if (sent_size != 1) { if (sent_size != 1) {
LOG_ERROR(Debug_GDBStub, "send failed"); LOG_ERROR(Debug_GDBStub, "send failed");
} }
@ -781,11 +781,11 @@ static void ReadRegister() {
LongToGdbHex(reply, RegRead(id, current_thread)); LongToGdbHex(reply, RegRead(id, current_thread));
} else if (id == PC_REGISTER) { } else if (id == PC_REGISTER) {
LongToGdbHex(reply, RegRead(id, current_thread)); LongToGdbHex(reply, RegRead(id, current_thread));
} else if (id == CPSR_REGISTER) { } else if (id == PSTATE_REGISTER) {
IntToGdbHex(reply, (u32)RegRead(id, current_thread)); IntToGdbHex(reply, static_cast<u32>(RegRead(id, current_thread)));
} else if (id >= UC_ARM64_REG_Q0 && id < FPSCR_REGISTER) { } else if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
LongToGdbHex(reply, RegRead(id, current_thread)); LongToGdbHex(reply, RegRead(id, current_thread));
} else if (id == FPSCR_REGISTER) { } else if (id == FPCR_REGISTER) {
LongToGdbHex(reply, RegRead(TODO_DUMMY_REG_998, current_thread)); LongToGdbHex(reply, RegRead(TODO_DUMMY_REG_998, current_thread));
} else { } else {
LongToGdbHex(reply, RegRead(TODO_DUMMY_REG_997, current_thread)); LongToGdbHex(reply, RegRead(TODO_DUMMY_REG_997, current_thread));
@ -811,7 +811,7 @@ static void ReadRegisters() {
bufptr += 16; bufptr += 16;
IntToGdbHex(bufptr, (u32)RegRead(CPSR_REGISTER, current_thread)); IntToGdbHex(bufptr, static_cast<u32>(RegRead(PSTATE_REGISTER, current_thread)));
bufptr += 8; bufptr += 8;
@ -843,11 +843,11 @@ static void WriteRegister() {
RegWrite(id, GdbHexToLong(buffer_ptr), current_thread); RegWrite(id, GdbHexToLong(buffer_ptr), current_thread);
} else if (id == PC_REGISTER) { } else if (id == PC_REGISTER) {
RegWrite(id, GdbHexToLong(buffer_ptr), current_thread); RegWrite(id, GdbHexToLong(buffer_ptr), current_thread);
} else if (id == CPSR_REGISTER) { } else if (id == PSTATE_REGISTER) {
RegWrite(id, GdbHexToInt(buffer_ptr), current_thread); RegWrite(id, GdbHexToInt(buffer_ptr), current_thread);
} else if (id >= UC_ARM64_REG_Q0 && id < FPSCR_REGISTER) { } else if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
RegWrite(id, GdbHexToLong(buffer_ptr), current_thread); RegWrite(id, GdbHexToLong(buffer_ptr), current_thread);
} else if (id == FPSCR_REGISTER) { } else if (id == FPCR_REGISTER) {
RegWrite(TODO_DUMMY_REG_998, GdbHexToLong(buffer_ptr), current_thread); RegWrite(TODO_DUMMY_REG_998, GdbHexToLong(buffer_ptr), current_thread);
} else { } else {
RegWrite(TODO_DUMMY_REG_997, GdbHexToLong(buffer_ptr), current_thread); RegWrite(TODO_DUMMY_REG_997, GdbHexToLong(buffer_ptr), current_thread);
@ -866,16 +866,16 @@ static void WriteRegisters() {
if (command_buffer[0] != 'G') if (command_buffer[0] != 'G')
return SendReply("E01"); return SendReply("E01");
for (u32 i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) { for (u32 i = 0, reg = 0; reg <= FPCR_REGISTER; i++, reg++) {
if (reg <= SP_REGISTER) { if (reg <= SP_REGISTER) {
RegWrite(reg, GdbHexToLong(buffer_ptr + i * 16), current_thread); RegWrite(reg, GdbHexToLong(buffer_ptr + i * 16), current_thread);
} else if (reg == PC_REGISTER) { } else if (reg == PC_REGISTER) {
RegWrite(PC_REGISTER, GdbHexToLong(buffer_ptr + i * 16), current_thread); RegWrite(PC_REGISTER, GdbHexToLong(buffer_ptr + i * 16), current_thread);
} else if (reg == CPSR_REGISTER) { } else if (reg == PSTATE_REGISTER) {
RegWrite(CPSR_REGISTER, GdbHexToInt(buffer_ptr + i * 16), current_thread); RegWrite(PSTATE_REGISTER, GdbHexToInt(buffer_ptr + i * 16), current_thread);
} else if (reg >= UC_ARM64_REG_Q0 && reg < FPSCR_REGISTER) { } else if (reg >= UC_ARM64_REG_Q0 && reg < FPCR_REGISTER) {
RegWrite(reg, GdbHexToLong(buffer_ptr + i * 16), current_thread); RegWrite(reg, GdbHexToLong(buffer_ptr + i * 16), current_thread);
} else if (reg == FPSCR_REGISTER) { } else if (reg == FPCR_REGISTER) {
RegWrite(TODO_DUMMY_REG_998, GdbHexToLong(buffer_ptr + i * 16), current_thread); RegWrite(TODO_DUMMY_REG_998, GdbHexToLong(buffer_ptr + i * 16), current_thread);
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();

View file

@ -12,7 +12,7 @@
namespace IPC { namespace IPC {
/// Size of the command buffer area, in 32-bit words. /// Size of the command buffer area, in 32-bit words.
constexpr size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32); constexpr std::size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32);
// These errors are commonly returned by invalid IPC translations, so alias them here for // These errors are commonly returned by invalid IPC translations, so alias them here for
// convenience. // convenience.

View file

@ -152,8 +152,8 @@ public:
} }
void ValidateHeader() { void ValidateHeader() {
const size_t num_domain_objects = context->NumDomainObjects(); const std::size_t num_domain_objects = context->NumDomainObjects();
const size_t num_move_objects = context->NumMoveObjects(); const std::size_t num_move_objects = context->NumMoveObjects();
ASSERT_MSG(!num_domain_objects || !num_move_objects, ASSERT_MSG(!num_domain_objects || !num_move_objects,
"cannot move normal handles and domain objects"); "cannot move normal handles and domain objects");
ASSERT_MSG((index - datapayload_index) == normal_params_size, ASSERT_MSG((index - datapayload_index) == normal_params_size,
@ -329,10 +329,10 @@ public:
T PopRaw(); T PopRaw();
template <typename T> template <typename T>
Kernel::SharedPtr<T> GetMoveObject(size_t index); Kernel::SharedPtr<T> GetMoveObject(std::size_t index);
template <typename T> template <typename T>
Kernel::SharedPtr<T> GetCopyObject(size_t index); Kernel::SharedPtr<T> GetCopyObject(std::size_t index);
template <class T> template <class T>
std::shared_ptr<T> PopIpcInterface() { std::shared_ptr<T> PopIpcInterface() {
@ -406,12 +406,12 @@ void RequestParser::Pop(First& first_value, Other&... other_values) {
} }
template <typename T> template <typename T>
Kernel::SharedPtr<T> RequestParser::GetMoveObject(size_t index) { Kernel::SharedPtr<T> RequestParser::GetMoveObject(std::size_t index) {
return context->GetMoveObject<T>(index); return context->GetMoveObject<T>(index);
} }
template <typename T> template <typename T>
Kernel::SharedPtr<T> RequestParser::GetCopyObject(size_t index) { Kernel::SharedPtr<T> RequestParser::GetCopyObject(std::size_t index) {
return context->GetCopyObject<T>(index); return context->GetCopyObject<T>(index);
} }

View file

@ -35,8 +35,9 @@ static ResultCode WaitForAddress(VAddr address, s64 timeout) {
// Gets the threads waiting on an address. // Gets the threads waiting on an address.
static std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) { static std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) {
const auto RetrieveWaitingThreads = const auto RetrieveWaitingThreads = [](std::size_t core_index,
[](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) { std::vector<SharedPtr<Thread>>& waiting_threads,
VAddr arb_addr) {
const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); const auto& scheduler = Core::System::GetInstance().Scheduler(core_index);
auto& thread_list = scheduler->GetThreadList(); auto& thread_list = scheduler->GetThreadList();
@ -66,12 +67,12 @@ static std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address)
static void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wake) { static void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wake) {
// Only process up to 'target' threads, unless 'target' is <= 0, in which case process // Only process up to 'target' threads, unless 'target' is <= 0, in which case process
// them all. // them all.
size_t last = waiting_threads.size(); std::size_t last = waiting_threads.size();
if (num_to_wake > 0) if (num_to_wake > 0)
last = num_to_wake; last = num_to_wake;
// Signal the waiting threads. // Signal the waiting threads.
for (size_t i = 0; i < last; i++) { for (std::size_t i = 0; i < last; i++) {
ASSERT(waiting_threads[i]->status == ThreadStatus::WaitArb); ASSERT(waiting_threads[i]->status == ThreadStatus::WaitArb);
waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS);
waiting_threads[i]->arb_wait_address = 0; waiting_threads[i]->arb_wait_address = 0;

View file

@ -17,6 +17,7 @@ enum {
// Confirmed Switch OS error codes // Confirmed Switch OS error codes
MaxConnectionsReached = 7, MaxConnectionsReached = 7,
InvalidSize = 101,
InvalidAddress = 102, InvalidAddress = 102,
HandleTableFull = 105, HandleTableFull = 105,
InvalidMemoryState = 106, InvalidMemoryState = 106,
@ -29,6 +30,7 @@ enum {
SynchronizationCanceled = 118, SynchronizationCanceled = 118,
TooLarge = 119, TooLarge = 119,
InvalidEnumValue = 120, InvalidEnumValue = 120,
NoSuchEntry = 121,
InvalidState = 125, InvalidState = 125,
ResourceLimitExceeded = 132, ResourceLimitExceeded = 132,
}; };
@ -55,6 +57,7 @@ constexpr ResultCode ERR_INVALID_MEMORY_PERMISSIONS(ErrorModule::Kernel,
ErrCodes::InvalidMemoryPermissions); ErrCodes::InvalidMemoryPermissions);
constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle); constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle);
constexpr ResultCode ERR_INVALID_PROCESSOR_ID(ErrorModule::Kernel, ErrCodes::InvalidProcessorId); constexpr ResultCode ERR_INVALID_PROCESSOR_ID(ErrorModule::Kernel, ErrCodes::InvalidProcessorId);
constexpr ResultCode ERR_INVALID_SIZE(ErrorModule::Kernel, ErrCodes::InvalidSize);
constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState); constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState);
constexpr ResultCode ERR_INVALID_THREAD_PRIORITY(ErrorModule::Kernel, constexpr ResultCode ERR_INVALID_THREAD_PRIORITY(ErrorModule::Kernel,
ErrCodes::InvalidThreadPriority); ErrCodes::InvalidThreadPriority);
@ -63,7 +66,7 @@ constexpr ResultCode ERR_INVALID_OBJECT_ADDR(-1);
constexpr ResultCode ERR_NOT_AUTHORIZED(-1); constexpr ResultCode ERR_NOT_AUTHORIZED(-1);
/// Alternate code returned instead of ERR_INVALID_HANDLE in some code paths. /// Alternate code returned instead of ERR_INVALID_HANDLE in some code paths.
constexpr ResultCode ERR_INVALID_HANDLE_OS(-1); constexpr ResultCode ERR_INVALID_HANDLE_OS(-1);
constexpr ResultCode ERR_NOT_FOUND(-1); constexpr ResultCode ERR_NOT_FOUND(ErrorModule::Kernel, ErrCodes::NoSuchEntry);
constexpr ResultCode RESULT_TIMEOUT(ErrorModule::Kernel, ErrCodes::Timeout); constexpr ResultCode RESULT_TIMEOUT(ErrorModule::Kernel, ErrCodes::Timeout);
/// Returned when Accept() is called on a port with no sessions to be accepted. /// Returned when Accept() is called on a port with no sessions to be accepted.
constexpr ResultCode ERR_NO_PENDING_SESSIONS(-1); constexpr ResultCode ERR_NO_PENDING_SESSIONS(-1);

View file

@ -65,7 +65,7 @@ ResultCode HandleTable::Close(Handle handle) {
} }
bool HandleTable::IsValid(Handle handle) const { bool HandleTable::IsValid(Handle handle) const {
size_t slot = GetSlot(handle); std::size_t slot = GetSlot(handle);
u16 generation = GetGeneration(handle); u16 generation = GetGeneration(handle);
return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation; return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation;

View file

@ -93,7 +93,7 @@ private:
* This is the maximum limit of handles allowed per process in CTR-OS. It can be further * This is the maximum limit of handles allowed per process in CTR-OS. It can be further
* reduced by ExHeader values, but this is not emulated here. * reduced by ExHeader values, but this is not emulated here.
*/ */
static const size_t MAX_COUNT = 4096; static const std::size_t MAX_COUNT = 4096;
static u16 GetSlot(Handle handle) { static u16 GetSlot(Handle handle) {
return handle >> 15; return handle >> 15;

View file

@ -42,9 +42,9 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
Kernel::SharedPtr<Kernel::Event> event) { Kernel::SharedPtr<Kernel::Event> event) {
// Put the client thread to sleep until the wait event is signaled or the timeout expires. // Put the client thread to sleep until the wait event is signaled or the timeout expires.
thread->wakeup_callback = thread->wakeup_callback = [context = *this, callback](
[context = *this, callback](ThreadWakeupReason reason, SharedPtr<Thread> thread, ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object, size_t index) mutable -> bool { SharedPtr<WaitObject> object, std::size_t index) mutable -> bool {
ASSERT(thread->status == ThreadStatus::WaitHLEEvent); ASSERT(thread->status == ThreadStatus::WaitHLEEvent);
callback(thread, context, reason); callback(thread, context, reason);
context.WriteToOutgoingCommandBuffer(*thread); context.WriteToOutgoingCommandBuffer(*thread);
@ -199,7 +199,7 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(u32_le* src_cmdb
} }
// The data_size already includes the payload header, the padding and the domain header. // The data_size already includes the payload header, the padding and the domain header.
size_t size = data_payload_offset + command_header->data_size - std::size_t size = data_payload_offset + command_header->data_size -
sizeof(IPC::DataPayloadHeader) / sizeof(u32) - 4; sizeof(IPC::DataPayloadHeader) / sizeof(u32) - 4;
if (domain_message_header) if (domain_message_header)
size -= sizeof(IPC::DomainMessageHeader) / sizeof(u32); size -= sizeof(IPC::DomainMessageHeader) / sizeof(u32);
@ -217,7 +217,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(const Thread& thread)
ParseCommandBuffer(cmd_buf.data(), false); ParseCommandBuffer(cmd_buf.data(), false);
// The data_size already includes the payload header, the padding and the domain header. // The data_size already includes the payload header, the padding and the domain header.
size_t size = data_payload_offset + command_header->data_size - std::size_t size = data_payload_offset + command_header->data_size -
sizeof(IPC::DataPayloadHeader) / sizeof(u32) - 4; sizeof(IPC::DataPayloadHeader) / sizeof(u32) - 4;
if (domain_message_header) if (domain_message_header)
size -= sizeof(IPC::DomainMessageHeader) / sizeof(u32); size -= sizeof(IPC::DomainMessageHeader) / sizeof(u32);
@ -229,7 +229,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(const Thread& thread)
"Handle descriptor bit set but no handles to translate"); "Handle descriptor bit set but no handles to translate");
// We write the translated handles at a specific offset in the command buffer, this space // We write the translated handles at a specific offset in the command buffer, this space
// was already reserved when writing the header. // was already reserved when writing the header.
size_t current_offset = std::size_t current_offset =
(sizeof(IPC::CommandHeader) + sizeof(IPC::HandleDescriptorHeader)) / sizeof(u32); (sizeof(IPC::CommandHeader) + sizeof(IPC::HandleDescriptorHeader)) / sizeof(u32);
ASSERT_MSG(!handle_descriptor_header->send_current_pid, "Sending PID is not implemented"); ASSERT_MSG(!handle_descriptor_header->send_current_pid, "Sending PID is not implemented");
@ -258,7 +258,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(const Thread& thread)
ASSERT(domain_message_header->num_objects == domain_objects.size()); ASSERT(domain_message_header->num_objects == domain_objects.size());
// Write the domain objects to the command buffer, these go after the raw untranslated data. // Write the domain objects to the command buffer, these go after the raw untranslated data.
// TODO(Subv): This completely ignores C buffers. // TODO(Subv): This completely ignores C buffers.
size_t domain_offset = size - domain_message_header->num_objects; std::size_t domain_offset = size - domain_message_header->num_objects;
auto& request_handlers = server_session->domain_request_handlers; auto& request_handlers = server_session->domain_request_handlers;
for (auto& object : domain_objects) { for (auto& object : domain_objects) {
@ -291,14 +291,15 @@ std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const {
return buffer; return buffer;
} }
size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size, int buffer_index) const { std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
int buffer_index) const {
if (size == 0) { if (size == 0) {
LOG_WARNING(Core, "skip empty buffer write"); LOG_WARNING(Core, "skip empty buffer write");
return 0; return 0;
} }
const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[buffer_index].Size()}; const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[buffer_index].Size()};
const size_t buffer_size{GetWriteBufferSize(buffer_index)}; const std::size_t buffer_size{GetWriteBufferSize(buffer_index)};
if (size > buffer_size) { if (size > buffer_size) {
LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size, LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
buffer_size); buffer_size);
@ -314,13 +315,13 @@ size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size, int buffe
return size; return size;
} }
size_t HLERequestContext::GetReadBufferSize(int buffer_index) const { std::size_t HLERequestContext::GetReadBufferSize(int buffer_index) const {
const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[buffer_index].Size()}; const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[buffer_index].Size()};
return is_buffer_a ? BufferDescriptorA()[buffer_index].Size() return is_buffer_a ? BufferDescriptorA()[buffer_index].Size()
: BufferDescriptorX()[buffer_index].Size(); : BufferDescriptorX()[buffer_index].Size();
} }
size_t HLERequestContext::GetWriteBufferSize(int buffer_index) const { std::size_t HLERequestContext::GetWriteBufferSize(int buffer_index) const {
const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[buffer_index].Size()}; const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[buffer_index].Size()};
return is_buffer_b ? BufferDescriptorB()[buffer_index].Size() return is_buffer_b ? BufferDescriptorB()[buffer_index].Size()
: BufferDescriptorC()[buffer_index].Size(); : BufferDescriptorC()[buffer_index].Size();

View file

@ -170,7 +170,7 @@ public:
std::vector<u8> ReadBuffer(int buffer_index = 0) const; std::vector<u8> ReadBuffer(int buffer_index = 0) const;
/// Helper function to write a buffer using the appropriate buffer descriptor /// Helper function to write a buffer using the appropriate buffer descriptor
size_t WriteBuffer(const void* buffer, size_t size, int buffer_index = 0) const; std::size_t WriteBuffer(const void* buffer, std::size_t size, int buffer_index = 0) const;
/* Helper function to write a buffer using the appropriate buffer descriptor /* Helper function to write a buffer using the appropriate buffer descriptor
* *
@ -182,7 +182,7 @@ public:
*/ */
template <typename ContiguousContainer, template <typename ContiguousContainer,
typename = std::enable_if_t<!std::is_pointer_v<ContiguousContainer>>> typename = std::enable_if_t<!std::is_pointer_v<ContiguousContainer>>>
size_t WriteBuffer(const ContiguousContainer& container, int buffer_index = 0) const { std::size_t WriteBuffer(const ContiguousContainer& container, int buffer_index = 0) const {
using ContiguousType = typename ContiguousContainer::value_type; using ContiguousType = typename ContiguousContainer::value_type;
static_assert(std::is_trivially_copyable_v<ContiguousType>, static_assert(std::is_trivially_copyable_v<ContiguousType>,
@ -193,19 +193,19 @@ public:
} }
/// Helper function to get the size of the input buffer /// Helper function to get the size of the input buffer
size_t GetReadBufferSize(int buffer_index = 0) const; std::size_t GetReadBufferSize(int buffer_index = 0) const;
/// Helper function to get the size of the output buffer /// Helper function to get the size of the output buffer
size_t GetWriteBufferSize(int buffer_index = 0) const; std::size_t GetWriteBufferSize(int buffer_index = 0) const;
template <typename T> template <typename T>
SharedPtr<T> GetCopyObject(size_t index) { SharedPtr<T> GetCopyObject(std::size_t index) {
ASSERT(index < copy_objects.size()); ASSERT(index < copy_objects.size());
return DynamicObjectCast<T>(copy_objects[index]); return DynamicObjectCast<T>(copy_objects[index]);
} }
template <typename T> template <typename T>
SharedPtr<T> GetMoveObject(size_t index) { SharedPtr<T> GetMoveObject(std::size_t index) {
ASSERT(index < move_objects.size()); ASSERT(index < move_objects.size());
return DynamicObjectCast<T>(move_objects[index]); return DynamicObjectCast<T>(move_objects[index]);
} }
@ -223,7 +223,7 @@ public:
} }
template <typename T> template <typename T>
std::shared_ptr<T> GetDomainRequestHandler(size_t index) const { std::shared_ptr<T> GetDomainRequestHandler(std::size_t index) const {
return std::static_pointer_cast<T>(domain_request_handlers[index]); return std::static_pointer_cast<T>(domain_request_handlers[index]);
} }
@ -240,15 +240,15 @@ public:
domain_objects.clear(); domain_objects.clear();
} }
size_t NumMoveObjects() const { std::size_t NumMoveObjects() const {
return move_objects.size(); return move_objects.size();
} }
size_t NumCopyObjects() const { std::size_t NumCopyObjects() const {
return copy_objects.size(); return copy_objects.size();
} }
size_t NumDomainObjects() const { std::size_t NumDomainObjects() const {
return domain_objects.size(); return domain_objects.size();
} }

View file

@ -62,7 +62,7 @@ ResultCode Mutex::TryAcquire(HandleTable& handle_table, VAddr address, Handle ho
Handle requesting_thread_handle) { Handle requesting_thread_handle) {
// The mutex address must be 4-byte aligned // The mutex address must be 4-byte aligned
if ((address % sizeof(u32)) != 0) { if ((address % sizeof(u32)) != 0) {
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidAddress); return ERR_INVALID_ADDRESS;
} }
SharedPtr<Thread> holding_thread = handle_table.Get<Thread>(holding_thread_handle); SharedPtr<Thread> holding_thread = handle_table.Get<Thread>(holding_thread_handle);
@ -100,7 +100,7 @@ ResultCode Mutex::TryAcquire(HandleTable& handle_table, VAddr address, Handle ho
ResultCode Mutex::Release(VAddr address) { ResultCode Mutex::Release(VAddr address) {
// The mutex address must be 4-byte aligned // The mutex address must be 4-byte aligned
if ((address % sizeof(u32)) != 0) { if ((address % sizeof(u32)) != 0) {
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidAddress); return ERR_INVALID_ADDRESS;
} }
auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(GetCurrentThread(), address); auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(GetCurrentThread(), address);

View file

@ -40,8 +40,8 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) {
return process; return process;
} }
void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { void Process::ParseKernelCaps(const u32* kernel_caps, std::size_t len) {
for (size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
u32 descriptor = kernel_caps[i]; u32 descriptor = kernel_caps[i];
u32 type = descriptor >> 20; u32 type = descriptor >> 20;
@ -211,7 +211,7 @@ ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
"Shared memory exceeds bounds of mapped block"); "Shared memory exceeds bounds of mapped block");
const std::shared_ptr<std::vector<u8>>& backing_block = vma->second.backing_block; const std::shared_ptr<std::vector<u8>>& backing_block = vma->second.backing_block;
size_t backing_block_offset = vma->second.offset + vma_offset; std::size_t backing_block_offset = vma->second.offset + vma_offset;
CASCADE_RESULT(auto new_vma, CASCADE_RESULT(auto new_vma,
vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size, vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size,

View file

@ -59,7 +59,7 @@ class ResourceLimit;
struct CodeSet final : public Object { struct CodeSet final : public Object {
struct Segment { struct Segment {
size_t offset = 0; std::size_t offset = 0;
VAddr addr = 0; VAddr addr = 0;
u32 size = 0; u32 size = 0;
}; };
@ -164,7 +164,7 @@ public:
* Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them
* to this process. * to this process.
*/ */
void ParseKernelCaps(const u32* kernel_caps, size_t len); void ParseKernelCaps(const u32* kernel_caps, std::size_t len);
/** /**
* Applies address space changes and launches the process main thread. * Applies address space changes and launches the process main thread.

View file

@ -119,7 +119,7 @@ public:
/// Backing memory for this shared memory block. /// Backing memory for this shared memory block.
std::shared_ptr<std::vector<u8>> backing_block; std::shared_ptr<std::vector<u8>> backing_block;
/// Offset into the backing block for this shared memory. /// Offset into the backing block for this shared memory.
size_t backing_block_offset; std::size_t backing_block_offset;
/// Size of the memory block. Page-aligned. /// Size of the memory block. Page-aligned.
u64 size; u64 size;
/// Permission restrictions applied to the process which created the block. /// Permission restrictions applied to the process which created the block.

View file

@ -35,10 +35,21 @@
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Kernel { namespace Kernel {
namespace {
constexpr bool Is4KBAligned(VAddr address) {
return (address & 0xFFF) == 0;
}
} // Anonymous namespace
/// Set the process heap to a given Size. It can both extend and shrink the heap. /// Set the process heap to a given Size. It can both extend and shrink the heap.
static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size);
// Size must be a multiple of 0x200000 (2MB) and be equal to or less than 4GB.
if ((heap_size & 0xFFFFFFFE001FFFFF) != 0) {
return ERR_INVALID_SIZE;
}
auto& process = *Core::CurrentProcess(); auto& process = *Core::CurrentProcess();
CASCADE_RESULT(*heap_addr, CASCADE_RESULT(*heap_addr,
process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite)); process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite));
@ -56,6 +67,15 @@ static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state
static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
src_addr, size); src_addr, size);
if (!Is4KBAligned(dst_addr) || !Is4KBAligned(src_addr)) {
return ERR_INVALID_ADDRESS;
}
if (size == 0 || !Is4KBAligned(size)) {
return ERR_INVALID_SIZE;
}
return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size); return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size);
} }
@ -63,6 +83,15 @@ static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
src_addr, size); src_addr, size);
if (!Is4KBAligned(dst_addr) || !Is4KBAligned(src_addr)) {
return ERR_INVALID_ADDRESS;
}
if (size == 0 || !Is4KBAligned(size)) {
return ERR_INVALID_SIZE;
}
return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size); return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size);
} }
@ -146,7 +175,7 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
/// Default thread wakeup callback for WaitSynchronization /// Default thread wakeup callback for WaitSynchronization
static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object, size_t index) { SharedPtr<WaitObject> object, std::size_t index) {
ASSERT(thread->status == ThreadStatus::WaitSynchAny); ASSERT(thread->status == ThreadStatus::WaitSynchAny);
if (reason == ThreadWakeupReason::Timeout) { if (reason == ThreadWakeupReason::Timeout) {
@ -251,6 +280,10 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
"requesting_current_thread_handle=0x{:08X}", "requesting_current_thread_handle=0x{:08X}",
holding_thread_handle, mutex_addr, requesting_thread_handle); holding_thread_handle, mutex_addr, requesting_thread_handle);
if (Memory::IsKernelVirtualAddress(mutex_addr)) {
return ERR_INVALID_ADDRESS_STATE;
}
auto& handle_table = Core::System::GetInstance().Kernel().HandleTable(); auto& handle_table = Core::System::GetInstance().Kernel().HandleTable();
return Mutex::TryAcquire(handle_table, mutex_addr, holding_thread_handle, return Mutex::TryAcquire(handle_table, mutex_addr, holding_thread_handle,
requesting_thread_handle); requesting_thread_handle);
@ -260,6 +293,10 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
static ResultCode ArbitrateUnlock(VAddr mutex_addr) { static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr);
if (Memory::IsKernelVirtualAddress(mutex_addr)) {
return ERR_INVALID_ADDRESS_STATE;
}
return Mutex::Release(mutex_addr); return Mutex::Release(mutex_addr);
} }
@ -415,35 +452,43 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
"called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
shared_memory_handle, addr, size, permissions); shared_memory_handle, addr, size, permissions);
if (!Is4KBAligned(addr)) {
return ERR_INVALID_ADDRESS;
}
if (size == 0 || !Is4KBAligned(size)) {
return ERR_INVALID_SIZE;
}
const auto permissions_type = static_cast<MemoryPermission>(permissions);
if (permissions_type != MemoryPermission::Read &&
permissions_type != MemoryPermission::ReadWrite) {
LOG_ERROR(Kernel_SVC, "Invalid permissions=0x{:08X}", permissions);
return ERR_INVALID_MEMORY_PERMISSIONS;
}
auto& kernel = Core::System::GetInstance().Kernel(); auto& kernel = Core::System::GetInstance().Kernel();
auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle);
if (!shared_memory) { if (!shared_memory) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
MemoryPermission permissions_type = static_cast<MemoryPermission>(permissions);
switch (permissions_type) {
case MemoryPermission::Read:
case MemoryPermission::Write:
case MemoryPermission::ReadWrite:
case MemoryPermission::Execute:
case MemoryPermission::ReadExecute:
case MemoryPermission::WriteExecute:
case MemoryPermission::ReadWriteExecute:
case MemoryPermission::DontCare:
return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type, return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type,
MemoryPermission::DontCare); MemoryPermission::DontCare);
default:
LOG_ERROR(Kernel_SVC, "unknown permissions=0x{:08X}", permissions);
}
return RESULT_SUCCESS;
} }
static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) {
LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}", LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}",
shared_memory_handle, addr, size); shared_memory_handle, addr, size);
if (!Is4KBAligned(addr)) {
return ERR_INVALID_ADDRESS;
}
if (size == 0 || !Is4KBAligned(size)) {
return ERR_INVALID_SIZE;
}
auto& kernel = Core::System::GetInstance().Kernel(); auto& kernel = Core::System::GetInstance().Kernel();
auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle);
@ -524,7 +569,7 @@ static void ExitProcess() {
/// Creates a new thread /// Creates a new thread
static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top,
u32 priority, s32 processor_id) { u32 priority, s32 processor_id) {
std::string name = fmt::format("unknown-{:X}", entry_point); std::string name = fmt::format("thread-{:X}", entry_point);
if (priority > THREADPRIO_LOWEST) { if (priority > THREADPRIO_LOWEST) {
return ERR_INVALID_THREAD_PRIORITY; return ERR_INVALID_THREAD_PRIORITY;
@ -647,8 +692,9 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}", LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}",
condition_variable_addr, target); condition_variable_addr, target);
auto RetrieveWaitingThreads = auto RetrieveWaitingThreads = [](std::size_t core_index,
[](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr condvar_addr) { std::vector<SharedPtr<Thread>>& waiting_threads,
VAddr condvar_addr) {
const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); const auto& scheduler = Core::System::GetInstance().Scheduler(core_index);
auto& thread_list = scheduler->GetThreadList(); auto& thread_list = scheduler->GetThreadList();
@ -672,7 +718,7 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
// Only process up to 'target' threads, unless 'target' is -1, in which case process // Only process up to 'target' threads, unless 'target' is -1, in which case process
// them all. // them all.
size_t last = waiting_threads.size(); std::size_t last = waiting_threads.size();
if (target != -1) if (target != -1)
last = target; last = target;
@ -680,12 +726,12 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
if (last > waiting_threads.size()) if (last > waiting_threads.size())
return RESULT_SUCCESS; return RESULT_SUCCESS;
for (size_t index = 0; index < last; ++index) { for (std::size_t index = 0; index < last; ++index) {
auto& thread = waiting_threads[index]; auto& thread = waiting_threads[index];
ASSERT(thread->condvar_wait_address == condition_variable_addr); ASSERT(thread->condvar_wait_address == condition_variable_addr);
size_t current_core = Core::System::GetInstance().CurrentCoreIndex(); std::size_t current_core = Core::System::GetInstance().CurrentCoreIndex();
auto& monitor = Core::System::GetInstance().Monitor(); auto& monitor = Core::System::GetInstance().Monitor();
@ -898,12 +944,28 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size, LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size,
local_permissions, remote_permissions); local_permissions, remote_permissions);
// Size must be a multiple of 4KB and be less than or equal to
// approx. 8 GB (actually (1GB - 512B) * 8)
if (size == 0 || (size & 0xFFFFFFFE00000FFF) != 0) {
return ERR_INVALID_SIZE;
}
const auto local_perms = static_cast<MemoryPermission>(local_permissions);
if (local_perms != MemoryPermission::Read && local_perms != MemoryPermission::ReadWrite) {
return ERR_INVALID_MEMORY_PERMISSIONS;
}
const auto remote_perms = static_cast<MemoryPermission>(remote_permissions);
if (remote_perms != MemoryPermission::Read && remote_perms != MemoryPermission::ReadWrite &&
remote_perms != MemoryPermission::DontCare) {
return ERR_INVALID_MEMORY_PERMISSIONS;
}
auto& kernel = Core::System::GetInstance().Kernel(); auto& kernel = Core::System::GetInstance().Kernel();
auto& handle_table = kernel.HandleTable(); auto& handle_table = kernel.HandleTable();
auto shared_mem_handle = auto shared_mem_handle =
SharedMemory::Create(kernel, handle_table.Get<Process>(KernelHandle::CurrentProcess), size, SharedMemory::Create(kernel, handle_table.Get<Process>(KernelHandle::CurrentProcess), size,
static_cast<MemoryPermission>(local_permissions), local_perms, remote_perms);
static_cast<MemoryPermission>(remote_permissions));
CASCADE_RESULT(*handle, handle_table.Create(shared_mem_handle)); CASCADE_RESULT(*handle, handle_table.Create(shared_mem_handle));
return RESULT_SUCCESS; return RESULT_SUCCESS;

View file

@ -13,7 +13,9 @@
namespace Kernel { namespace Kernel {
#define PARAM(n) Core::CurrentArmInterface().GetReg(n) static inline u64 Param(int n) {
return Core::CurrentArmInterface().GetReg(n);
}
/** /**
* HLE a function return from the current ARM userland process * HLE a function return from the current ARM userland process
@ -28,23 +30,23 @@ static inline void FuncReturn(u64 res) {
template <ResultCode func(u64)> template <ResultCode func(u64)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func(PARAM(0)).raw); FuncReturn(func(Param(0)).raw);
} }
template <ResultCode func(u32)> template <ResultCode func(u32)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func((u32)PARAM(0)).raw); FuncReturn(func((u32)Param(0)).raw);
} }
template <ResultCode func(u32, u32)> template <ResultCode func(u32, u32)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func((u32)PARAM(0), (u32)PARAM(1)).raw); FuncReturn(func((u32)Param(0), (u32)Param(1)).raw);
} }
template <ResultCode func(u32*, u32)> template <ResultCode func(u32*, u32)>
void SvcWrap() { void SvcWrap() {
u32 param_1 = 0; u32 param_1 = 0;
u32 retval = func(&param_1, (u32)PARAM(1)).raw; u32 retval = func(&param_1, (u32)Param(1)).raw;
Core::CurrentArmInterface().SetReg(1, param_1); Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); FuncReturn(retval);
} }
@ -52,39 +54,39 @@ void SvcWrap() {
template <ResultCode func(u32*, u64)> template <ResultCode func(u32*, u64)>
void SvcWrap() { void SvcWrap() {
u32 param_1 = 0; u32 param_1 = 0;
u32 retval = func(&param_1, PARAM(1)).raw; u32 retval = func(&param_1, Param(1)).raw;
Core::CurrentArmInterface().SetReg(1, param_1); Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); FuncReturn(retval);
} }
template <ResultCode func(u64, s32)> template <ResultCode func(u64, s32)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func(PARAM(0), (s32)PARAM(1)).raw); FuncReturn(func(Param(0), (s32)Param(1)).raw);
} }
template <ResultCode func(u64*, u64)> template <ResultCode func(u64*, u64)>
void SvcWrap() { void SvcWrap() {
u64 param_1 = 0; u64 param_1 = 0;
u32 retval = func(&param_1, PARAM(1)).raw; u32 retval = func(&param_1, Param(1)).raw;
Core::CurrentArmInterface().SetReg(1, param_1); Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); FuncReturn(retval);
} }
template <ResultCode func(u32, u64)> template <ResultCode func(u32, u64)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func((u32)(PARAM(0) & 0xFFFFFFFF), PARAM(1)).raw); FuncReturn(func((u32)(Param(0) & 0xFFFFFFFF), Param(1)).raw);
} }
template <ResultCode func(u32, u32, u64)> template <ResultCode func(u32, u32, u64)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func((u32)(PARAM(0) & 0xFFFFFFFF), (u32)(PARAM(1) & 0xFFFFFFFF), PARAM(2)).raw); FuncReturn(func((u32)(Param(0) & 0xFFFFFFFF), (u32)(Param(1) & 0xFFFFFFFF), Param(2)).raw);
} }
template <ResultCode func(u32, u32*, u64*)> template <ResultCode func(u32, u32*, u64*)>
void SvcWrap() { void SvcWrap() {
u32 param_1 = 0; u32 param_1 = 0;
u64 param_2 = 0; u64 param_2 = 0;
ResultCode retval = func((u32)(PARAM(2) & 0xFFFFFFFF), &param_1, &param_2); ResultCode retval = func((u32)(Param(2) & 0xFFFFFFFF), &param_1, &param_2);
Core::CurrentArmInterface().SetReg(1, param_1); Core::CurrentArmInterface().SetReg(1, param_1);
Core::CurrentArmInterface().SetReg(2, param_2); Core::CurrentArmInterface().SetReg(2, param_2);
FuncReturn(retval.raw); FuncReturn(retval.raw);
@ -93,46 +95,46 @@ void SvcWrap() {
template <ResultCode func(u64, u64, u32, u32)> template <ResultCode func(u64, u64, u32, u32)>
void SvcWrap() { void SvcWrap() {
FuncReturn( FuncReturn(
func(PARAM(0), PARAM(1), (u32)(PARAM(3) & 0xFFFFFFFF), (u32)(PARAM(3) & 0xFFFFFFFF)).raw); func(Param(0), Param(1), (u32)(Param(3) & 0xFFFFFFFF), (u32)(Param(3) & 0xFFFFFFFF)).raw);
} }
template <ResultCode func(u32, u64, u32)> template <ResultCode func(u32, u64, u32)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func((u32)PARAM(0), PARAM(1), (u32)PARAM(2)).raw); FuncReturn(func((u32)Param(0), Param(1), (u32)Param(2)).raw);
} }
template <ResultCode func(u64, u64, u64)> template <ResultCode func(u64, u64, u64)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func(PARAM(0), PARAM(1), PARAM(2)).raw); FuncReturn(func(Param(0), Param(1), Param(2)).raw);
} }
template <ResultCode func(u32, u64, u64, u32)> template <ResultCode func(u32, u64, u64, u32)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func((u32)PARAM(0), PARAM(1), PARAM(2), (u32)PARAM(3)).raw); FuncReturn(func((u32)Param(0), Param(1), Param(2), (u32)Param(3)).raw);
} }
template <ResultCode func(u32, u64, u64)> template <ResultCode func(u32, u64, u64)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func((u32)PARAM(0), PARAM(1), PARAM(2)).raw); FuncReturn(func((u32)Param(0), Param(1), Param(2)).raw);
} }
template <ResultCode func(u32*, u64, u64, s64)> template <ResultCode func(u32*, u64, u64, s64)>
void SvcWrap() { void SvcWrap() {
u32 param_1 = 0; u32 param_1 = 0;
ResultCode retval = func(&param_1, PARAM(1), (u32)(PARAM(2) & 0xFFFFFFFF), (s64)PARAM(3)); ResultCode retval = func(&param_1, Param(1), (u32)(Param(2) & 0xFFFFFFFF), (s64)Param(3));
Core::CurrentArmInterface().SetReg(1, param_1); Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval.raw); FuncReturn(retval.raw);
} }
template <ResultCode func(u64, u64, u32, s64)> template <ResultCode func(u64, u64, u32, s64)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func(PARAM(0), PARAM(1), (u32)PARAM(2), (s64)PARAM(3)).raw); FuncReturn(func(Param(0), Param(1), (u32)Param(2), (s64)Param(3)).raw);
} }
template <ResultCode func(u64*, u64, u64, u64)> template <ResultCode func(u64*, u64, u64, u64)>
void SvcWrap() { void SvcWrap() {
u64 param_1 = 0; u64 param_1 = 0;
u32 retval = func(&param_1, PARAM(1), PARAM(2), PARAM(3)).raw; u32 retval = func(&param_1, Param(1), Param(2), Param(3)).raw;
Core::CurrentArmInterface().SetReg(1, param_1); Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); FuncReturn(retval);
} }
@ -141,7 +143,7 @@ template <ResultCode func(u32*, u64, u64, u64, u32, s32)>
void SvcWrap() { void SvcWrap() {
u32 param_1 = 0; u32 param_1 = 0;
u32 retval = u32 retval =
func(&param_1, PARAM(1), PARAM(2), PARAM(3), (u32)PARAM(4), (s32)(PARAM(5) & 0xFFFFFFFF)) func(&param_1, Param(1), Param(2), Param(3), (u32)Param(4), (s32)(Param(5) & 0xFFFFFFFF))
.raw; .raw;
Core::CurrentArmInterface().SetReg(1, param_1); Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); FuncReturn(retval);
@ -151,13 +153,13 @@ template <ResultCode func(MemoryInfo*, PageInfo*, u64)>
void SvcWrap() { void SvcWrap() {
MemoryInfo memory_info = {}; MemoryInfo memory_info = {};
PageInfo page_info = {}; PageInfo page_info = {};
u32 retval = func(&memory_info, &page_info, PARAM(2)).raw; u32 retval = func(&memory_info, &page_info, Param(2)).raw;
Memory::Write64(PARAM(0), memory_info.base_address); Memory::Write64(Param(0), memory_info.base_address);
Memory::Write64(PARAM(0) + 8, memory_info.size); Memory::Write64(Param(0) + 8, memory_info.size);
Memory::Write32(PARAM(0) + 16, memory_info.type); Memory::Write32(Param(0) + 16, memory_info.type);
Memory::Write32(PARAM(0) + 20, memory_info.attributes); Memory::Write32(Param(0) + 20, memory_info.attributes);
Memory::Write32(PARAM(0) + 24, memory_info.permission); Memory::Write32(Param(0) + 24, memory_info.permission);
FuncReturn(retval); FuncReturn(retval);
} }
@ -165,7 +167,7 @@ void SvcWrap() {
template <ResultCode func(u32*, u64, u64, u32)> template <ResultCode func(u32*, u64, u64, u32)>
void SvcWrap() { void SvcWrap() {
u32 param_1 = 0; u32 param_1 = 0;
u32 retval = func(&param_1, PARAM(1), PARAM(2), (u32)(PARAM(3) & 0xFFFFFFFF)).raw; u32 retval = func(&param_1, Param(1), Param(2), (u32)(Param(3) & 0xFFFFFFFF)).raw;
Core::CurrentArmInterface().SetReg(1, param_1); Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); FuncReturn(retval);
} }
@ -174,7 +176,7 @@ template <ResultCode func(Handle*, u64, u32, u32)>
void SvcWrap() { void SvcWrap() {
u32 param_1 = 0; u32 param_1 = 0;
u32 retval = u32 retval =
func(&param_1, PARAM(1), (u32)(PARAM(2) & 0xFFFFFFFF), (u32)(PARAM(3) & 0xFFFFFFFF)).raw; func(&param_1, Param(1), (u32)(Param(2) & 0xFFFFFFFF), (u32)(Param(3) & 0xFFFFFFFF)).raw;
Core::CurrentArmInterface().SetReg(1, param_1); Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval); FuncReturn(retval);
} }
@ -182,14 +184,14 @@ void SvcWrap() {
template <ResultCode func(u64, u32, s32, s64)> template <ResultCode func(u64, u32, s32, s64)>
void SvcWrap() { void SvcWrap() {
FuncReturn( FuncReturn(
func(PARAM(0), (u32)(PARAM(1) & 0xFFFFFFFF), (s32)(PARAM(2) & 0xFFFFFFFF), (s64)PARAM(3)) func(Param(0), (u32)(Param(1) & 0xFFFFFFFF), (s32)(Param(2) & 0xFFFFFFFF), (s64)Param(3))
.raw); .raw);
} }
template <ResultCode func(u64, u32, s32, s32)> template <ResultCode func(u64, u32, s32, s32)>
void SvcWrap() { void SvcWrap() {
FuncReturn(func(PARAM(0), (u32)(PARAM(1) & 0xFFFFFFFF), (s32)(PARAM(2) & 0xFFFFFFFF), FuncReturn(func(Param(0), (u32)(Param(1) & 0xFFFFFFFF), (s32)(Param(2) & 0xFFFFFFFF),
(s32)(PARAM(3) & 0xFFFFFFFF)) (s32)(Param(3) & 0xFFFFFFFF))
.raw); .raw);
} }
@ -219,20 +221,17 @@ void SvcWrap() {
template <void func(s64)> template <void func(s64)>
void SvcWrap() { void SvcWrap() {
func((s64)PARAM(0)); func((s64)Param(0));
} }
template <void func(u64, u64 len)> template <void func(u64, u64 len)>
void SvcWrap() { void SvcWrap() {
func(PARAM(0), PARAM(1)); func(Param(0), Param(1));
} }
template <void func(u64, u64, u64)> template <void func(u64, u64, u64)>
void SvcWrap() { void SvcWrap() {
func(PARAM(0), PARAM(1), PARAM(2)); func(Param(0), Param(1), Param(2));
} }
#undef PARAM
#undef FuncReturn
} // namespace Kernel } // namespace Kernel

View file

@ -217,8 +217,8 @@ static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAdd
context.cpu_registers[0] = arg; context.cpu_registers[0] = arg;
context.pc = entry_point; context.pc = entry_point;
context.sp = stack_top; context.sp = stack_top;
context.cpsr = 0; context.pstate = 0;
context.fpscr = 0; context.fpcr = 0;
} }
ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point, ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point,
@ -275,7 +275,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
available_slot = 0; // Use the first slot in the new page available_slot = 0; // Use the first slot in the new page
// Allocate some memory from the end of the linear heap for this region. // Allocate some memory from the end of the linear heap for this region.
const size_t offset = thread->tls_memory->size(); const std::size_t offset = thread->tls_memory->size();
thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0); thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0);
auto& vm_manager = owner_process->vm_manager; auto& vm_manager = owner_process->vm_manager;

View file

@ -254,7 +254,7 @@ public:
Handle callback_handle; Handle callback_handle;
using WakeupCallback = bool(ThreadWakeupReason reason, SharedPtr<Thread> thread, using WakeupCallback = bool(ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object, size_t index); SharedPtr<WaitObject> object, std::size_t index);
// Callback that will be invoked when the thread is resumed from a waiting state. If the thread // Callback that will be invoked when the thread is resumed from a waiting state. If the thread
// was waiting via WaitSynchronizationN then the object will be the last object that became // was waiting via WaitSynchronizationN then the object will be the last object that became
// available. In case of a timeout, the object will be nullptr. // available. In case of a timeout, the object will be nullptr.

View file

@ -86,7 +86,7 @@ VMManager::VMAHandle VMManager::FindVMA(VAddr target) const {
ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target, ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
std::shared_ptr<std::vector<u8>> block, std::shared_ptr<std::vector<u8>> block,
size_t offset, u64 size, std::size_t offset, u64 size,
MemoryState state) { MemoryState state) {
ASSERT(block != nullptr); ASSERT(block != nullptr);
ASSERT(offset + size <= block->size()); ASSERT(offset + size <= block->size());

View file

@ -81,7 +81,7 @@ struct VirtualMemoryArea {
/// Memory block backing this VMA. /// Memory block backing this VMA.
std::shared_ptr<std::vector<u8>> backing_block = nullptr; std::shared_ptr<std::vector<u8>> backing_block = nullptr;
/// Offset into the backing_memory the mapping starts from. /// Offset into the backing_memory the mapping starts from.
size_t offset = 0; std::size_t offset = 0;
// Settings for type = BackingMemory // Settings for type = BackingMemory
/// Pointer backing this VMA. It will not be destroyed or freed when the VMA is removed. /// Pointer backing this VMA. It will not be destroyed or freed when the VMA is removed.
@ -147,7 +147,7 @@ public:
* @param state MemoryState tag to attach to the VMA. * @param state MemoryState tag to attach to the VMA.
*/ */
ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block, ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block,
size_t offset, u64 size, MemoryState state); std::size_t offset, u64 size, MemoryState state);
/** /**
* Maps an unmanaged host memory pointer at a given address. * Maps an unmanaged host memory pointer at a given address.

View file

@ -81,7 +81,7 @@ void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) {
} }
} }
size_t index = thread->GetWaitObjectIndex(this); std::size_t index = thread->GetWaitObjectIndex(this);
for (auto& object : thread->wait_objects) for (auto& object : thread->wait_objects)
object->RemoveWaitingThread(thread.get()); object->RemoveWaitingThread(thread.get());

Some files were not shown because too many files have changed in this diff Show more