From 773e4de3cadb8743920771e121dcfa51c26a89dd Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 30 Jun 2026 23:41:24 +0200 Subject: [PATCH] Move unsafe raw pointer write_to_ptr and read_from_ptr to write_to_ptr_unsafe and read_from_ptr_unsafe --- rpcs3/Crypto/unpkg.cpp | 8 +- rpcs3/Crypto/unself.cpp | 128 ++++++++++++----------- rpcs3/Crypto/unself.h | 29 +++-- rpcs3/Emu/Cell/Modules/cellAdec.cpp | 12 +-- rpcs3/Emu/Cell/Modules/cellAtracXdec.cpp | 2 +- rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp | 34 +++--- rpcs3/Emu/Cell/Modules/cellSysmodule.cpp | 22 ++-- rpcs3/Emu/Cell/PPUThread.cpp | 34 +++--- rpcs3/Emu/Cell/SPUThread.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_game.cpp | 4 +- rpcs3/Emu/Io/Dimensions.cpp | 10 +- rpcs3/Emu/Io/Skylander.cpp | 8 +- rpcs3/Emu/Io/Skylander.h | 3 +- rpcs3/Emu/Memory/vm.cpp | 4 +- rpcs3/Emu/NP/np_handler.cpp | 24 ++--- rpcs3/Emu/NP/np_handler.h | 6 +- rpcs3/Emu/RSX/Common/surface_store.h | 25 +++-- rpcs3/Emu/RSX/NV47/HW/nv4097.cpp | 2 +- rpcs3/Emu/RSX/RSXFIFO.cpp | 2 +- rpcs3/Emu/RSX/RSXThread.cpp | 4 +- rpcs3/Emu/System.cpp | 2 +- rpcs3/Loader/TAR.cpp | 2 +- rpcs3/rpcs3qt/memory_viewer_panel.cpp | 2 +- rpcs3/rpcs3qt/skylander_dialog.cpp | 19 ++-- rpcs3/tests/test_types_util.cpp | 77 +++++--------- rpcs3/util/types.hpp | 54 +++++++--- 26 files changed, 262 insertions(+), 257 deletions(-) diff --git a/rpcs3/Crypto/unpkg.cpp b/rpcs3/Crypto/unpkg.cpp index aad8555053..66fd5da416 100644 --- a/rpcs3/Crypto/unpkg.cpp +++ b/rpcs3/Crypto/unpkg.cpp @@ -1432,8 +1432,8 @@ usz package_reader::decrypt(u64 offset, u64 size, const uchar* key, void* local_ sha1(reinterpret_cast(input), sizeof(input), hash.data); - const u128 v = read_from_ptr(out_data, i * 16); - write_to_ptr(out_data, i * 16, v ^ read_from_ptr(hash.data)); + const u128 v = read_from_ptr_unsafe(out_data, i * 16); + write_to_ptr_unsafe(out_data, i * 16, v ^ read_from_ptr(hash.data)); } } else if (m_header.pkg_type == PKG_RELEASE_TYPE_RELEASE) @@ -1453,8 +1453,8 @@ usz package_reader::decrypt(u64 offset, u64 size, const uchar* key, void* local_ aes_crypt_ecb(&ctx, AES_ENCRYPT, reinterpret_cast(&input), reinterpret_cast(&key)); - const u128 v = read_from_ptr(out_data, i * 16); - write_to_ptr(out_data, i * 16, v ^ key); + const u128 v = read_from_ptr_unsafe(out_data, i * 16); + write_to_ptr_unsafe(out_data, i * 16, v ^ key); } } else diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index c0eac8d9c7..28c33d14ee 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -332,12 +332,14 @@ void supplemental_header::Show() const } } -void MetadataInfo::Load(u8* in) +void MetadataInfo::Load(std::span in) { - memcpy(key, in, 0x10); - memcpy(key_pad, in + 0x10, 0x10); - memcpy(iv, in + 0x20, 0x10); - memcpy(iv_pad, in + 0x30, 0x10); + ensure(in.size() >= sizeof(MetadataInfo)); + + std::memcpy(key, in.data(), 0x10); + std::memcpy(key_pad, in.data() + 0x10, 0x10); + std::memcpy(iv, in.data() + 0x20, 0x10); + std::memcpy(iv_pad, in.data() + 0x30, 0x10); } void MetadataInfo::Show() const @@ -360,10 +362,10 @@ void MetadataInfo::Show() const self_log.notice("IV pad: %s", iv_pad_str.c_str()); } -void MetadataHeader::Load(u8* in) +void MetadataHeader::Load(std::span in) { // Endian swap. - signature_input_length = read_from_ptr>(in); + signature_input_length = read_from_ptr>(in, 0); unknown1 = read_from_ptr>(in, 8); section_count = read_from_ptr>(in, 12); key_count = read_from_ptr>(in, 16); @@ -383,10 +385,10 @@ void MetadataHeader::Show() const self_log.notice("Unknown3: 0x%08x", unknown3); } -void MetadataSectionHeader::Load(u8* in) +void MetadataSectionHeader::Load(std::span in) { // Endian swap. - data_offset = read_from_ptr>(in); + data_offset = read_from_ptr>(in, 0); data_size = read_from_ptr>(in, 8); type = read_from_ptr>(in, 16); program_idx = read_from_ptr>(in, 20); @@ -602,7 +604,6 @@ void ext_hdr::Load(const fs::file& f) SCEDecrypter::SCEDecrypter(const fs::file& s) : sce_f(s) - , data_buf_length(0) { } @@ -625,34 +626,33 @@ bool SCEDecrypter::LoadHeaders() bool SCEDecrypter::LoadMetadata(const u8 erk[32], const u8 riv[16]) { aes_context aes; - const auto metadata_info = std::make_unique(sizeof(meta_info)); - const auto metadata_headers_size = sce_hdr.se_hsize - (sizeof(sce_hdr) + sce_hdr.se_meta + sizeof(meta_info)); - const auto metadata_headers = std::make_unique(metadata_headers_size); + std::vector metadata_info(sizeof(meta_info)); + std::vector metadata_headers(sce_hdr.se_hsize - (sizeof(sce_hdr) + sce_hdr.se_meta + sizeof(meta_info))); // Locate and read the encrypted metadata info. sce_f.seek(sce_hdr.se_meta + sizeof(sce_hdr)); - sce_f.read(metadata_info.get(), sizeof(meta_info)); + sce_f.read(metadata_info.data(), metadata_info.size()); // Locate and read the encrypted metadata header and section header. sce_f.seek(sce_hdr.se_meta + sizeof(sce_hdr) + sizeof(meta_info)); - sce_f.read(metadata_headers.get(), metadata_headers_size); + sce_f.read(metadata_headers.data(), metadata_headers.size()); // Copy the necessary parameters. u8 metadata_key[0x20]; u8 metadata_iv[0x10]; - memcpy(metadata_key, erk, 0x20); - memcpy(metadata_iv, riv, 0x10); + std::memcpy(metadata_key, erk, 0x20); + std::memcpy(metadata_iv, riv, 0x10); // Check DEBUG flag. if ((sce_hdr.se_flags & 0x8000) != 0x8000) { // Decrypt the metadata info. aes_setkey_dec(&aes, metadata_key, 256); // AES-256 - aes_crypt_cbc(&aes, AES_DECRYPT, sizeof(meta_info), metadata_iv, metadata_info.get(), metadata_info.get()); + aes_crypt_cbc(&aes, AES_DECRYPT, metadata_info.size(), metadata_iv, metadata_info.data(), metadata_info.data()); } // Load the metadata info. - meta_info.Load(metadata_info.get()); + meta_info.Load(metadata_info); // If the padding is not NULL for the key or iv fields, the metadata info // is not properly decrypted. @@ -667,23 +667,28 @@ bool SCEDecrypter::LoadMetadata(const u8 erk[32], const u8 riv[16]) usz ctr_nc_off = 0; u8 ctr_stream_block[0x10]; aes_setkey_enc(&aes, meta_info.key, 128); - aes_crypt_ctr(&aes, metadata_headers_size, &ctr_nc_off, meta_info.iv, ctr_stream_block, metadata_headers.get(), metadata_headers.get()); + aes_crypt_ctr(&aes, metadata_headers.size(), &ctr_nc_off, meta_info.iv, ctr_stream_block, metadata_headers.data(), metadata_headers.data()); // Load the metadata header. - meta_hdr.Load(metadata_headers.get()); + meta_hdr.Load(metadata_headers); // Load the metadata section headers. meta_shdr.clear(); for (unsigned int i = 0; i < meta_hdr.section_count; i++) { + const usz shdr_offset = sizeof(meta_hdr) + sizeof(MetadataSectionHeader) * i; + ensure(metadata_headers.size() > shdr_offset); + meta_shdr.emplace_back(); - meta_shdr.back().Load(metadata_headers.get() + sizeof(meta_hdr) + sizeof(MetadataSectionHeader) * i); + meta_shdr.back().Load(std::span(metadata_headers.data() + shdr_offset, metadata_headers.size() - shdr_offset)); } // Copy the decrypted data keys. - data_keys_length = meta_hdr.key_count * 0x10; - data_keys = std::make_unique(data_keys_length); - memcpy(data_keys.get(), metadata_headers.get() + sizeof(meta_hdr) + meta_hdr.section_count * sizeof(MetadataSectionHeader), data_keys_length); + data_keys.resize(meta_hdr.key_count * 0x10); + + const usz data_keys_offset = sizeof(meta_hdr) + meta_hdr.section_count * sizeof(MetadataSectionHeader); + ensure(metadata_headers.size() >= (data_keys_offset + data_keys.size())); + std::memcpy(data_keys.data(), metadata_headers.data() + data_keys_offset, data_keys.size()); return true; } @@ -691,6 +696,7 @@ bool SCEDecrypter::LoadMetadata(const u8 erk[32], const u8 riv[16]) bool SCEDecrypter::DecryptData() { aes_context aes; + usz data_buf_length = 0; // Calculate the total data size. for (unsigned int i = 0; i < meta_hdr.section_count; i++) @@ -699,7 +705,7 @@ bool SCEDecrypter::DecryptData() } // Allocate a buffer to store decrypted data. - data_buf = std::make_unique(data_buf_length); + data_buf.resize(data_buf_length); // Set initial offset. u32 data_buf_offset = 0; @@ -719,8 +725,8 @@ bool SCEDecrypter::DecryptData() if ((meta_shdr[i].key_idx <= meta_hdr.key_count - 1) && (meta_shdr[i].iv_idx <= meta_hdr.key_count)) { // Get the key and iv from the previously stored key buffer. - memcpy(data_key, data_keys.get() + meta_shdr[i].key_idx * 0x10, 0x10); - memcpy(data_iv, data_keys.get() + meta_shdr[i].iv_idx * 0x10, 0x10); + std::memcpy(data_key, data_keys.data() + meta_shdr[i].key_idx * 0x10, 0x10); + std::memcpy(data_iv, data_keys.data() + meta_shdr[i].iv_idx * 0x10, 0x10); // Allocate a buffer to hold the data. auto buf = std::make_unique(meta_shdr[i].data_size); @@ -730,14 +736,14 @@ bool SCEDecrypter::DecryptData() sce_f.read(buf.get(), meta_shdr[i].data_size); // Zero out our ctr nonce. - memset(ctr_stream_block, 0, sizeof(ctr_stream_block)); + std::memset(ctr_stream_block, 0, sizeof(ctr_stream_block)); // Perform AES-CTR encryption on the data blocks. aes_setkey_enc(&aes, data_key, 128); aes_crypt_ctr(&aes, meta_shdr[i].data_size, &ctr_nc_off, data_iv, ctr_stream_block, buf.get(), buf.get()); // Copy the decrypted data. - memcpy(data_buf.get() + data_buf_offset, buf.get(), meta_shdr[i].data_size); + std::memcpy(data_buf.data() + data_buf_offset, buf.get(), meta_shdr[i].data_size); } } else @@ -745,7 +751,7 @@ bool SCEDecrypter::DecryptData() auto buf = std::make_unique(meta_shdr[i].data_size); sce_f.seek(meta_shdr[i].data_offset); sce_f.read(buf.get(), meta_shdr[i].data_size); - memcpy(data_buf.get() + data_buf_offset, buf.get(), meta_shdr[i].data_size); + std::memcpy(data_buf.data() + data_buf_offset, buf.get(), meta_shdr[i].data_size); } // Advance the buffer's offset. @@ -767,7 +773,7 @@ std::vector SCEDecrypter::MakeFile() for (u32 i = 0; i < meta_hdr.section_count; i++) { const MetadataSectionHeader& hdr = meta_shdr[i]; - const u8* src = data_buf.get() + data_buf_offset; + const u8* src = data_buf.data() + data_buf_offset; fs::file out_f = fs::make_stream>(); bool is_valid = true; @@ -1071,7 +1077,7 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size) aes_crypt_ecb(&aes, AES_DECRYPT, npdrm_key, npdrm_key); // IV is empty. - memset(npdrm_iv, 0, 0x10); + std::memset(npdrm_iv, 0, 0x10); // Use our final key to decrypt the NPDRM layer. aes_setkey_dec(&aes, npdrm_key, 128); @@ -1097,20 +1103,19 @@ const NPD_HEADER* SELFDecrypter::GetNPDHeader() const bool SELFDecrypter::LoadMetadata(const u8* klic_key) { aes_context aes; - const auto metadata_info = std::make_unique(sizeof(meta_info)); - const auto metadata_headers_size = sce_hdr.se_hsize - (sizeof(sce_hdr) + sce_hdr.se_meta + sizeof(meta_info)); - const auto metadata_headers = std::make_unique(metadata_headers_size); + std::vector metadata_info(sizeof(meta_info)); + std::vector metadata_headers(sce_hdr.se_hsize - (sizeof(sce_hdr) + sce_hdr.se_meta + sizeof(meta_info))); // Locate and read the encrypted metadata info. self_f.seek(sce_hdr.se_meta + sizeof(sce_hdr)); - self_f.read(metadata_info.get(), sizeof(meta_info)); + self_f.read(metadata_info.data(), metadata_info.size()); // Locate and read the encrypted metadata header and section header. self_f.seek(sce_hdr.se_meta + sizeof(sce_hdr) + sizeof(meta_info)); - self_f.read(metadata_headers.get(), metadata_headers_size); + self_f.read(metadata_headers.data(), metadata_headers.size()); // Find the right keyset from the key vault. - SELF_KEY keyset = key_v.FindSelfKey(m_prog_id_hdr.program_type, sce_hdr.se_flags, m_prog_id_hdr.program_sceversion); + const SELF_KEY keyset = key_v.FindSelfKey(m_prog_id_hdr.program_type, sce_hdr.se_flags, m_prog_id_hdr.program_sceversion); // Set klic if given if (klic_key) @@ -1126,16 +1131,16 @@ bool SELFDecrypter::LoadMetadata(const u8* klic_key) if ((sce_hdr.se_flags & 0x8000) != 0x8000) { // Decrypt the NPDRM layer. - if (!DecryptNPDRM(metadata_info.get(), sizeof(meta_info))) + if (!DecryptNPDRM(metadata_info.data(), ::size32(metadata_info))) return false; // Decrypt the metadata info. aes_setkey_dec(&aes, metadata_key, 256); // AES-256 - aes_crypt_cbc(&aes, AES_DECRYPT, sizeof(meta_info), metadata_iv, metadata_info.get(), metadata_info.get()); + aes_crypt_cbc(&aes, AES_DECRYPT, metadata_info.size(), metadata_iv, metadata_info.data(), metadata_info.data()); } // Load the metadata info. - meta_info.Load(metadata_info.get()); + meta_info.Load(metadata_info); // If the padding is not NULL for the key or iv fields, the metadata info // is not properly decrypted. @@ -1150,23 +1155,28 @@ bool SELFDecrypter::LoadMetadata(const u8* klic_key) usz ctr_nc_off = 0; u8 ctr_stream_block[0x10]; aes_setkey_enc(&aes, meta_info.key, 128); - aes_crypt_ctr(&aes, metadata_headers_size, &ctr_nc_off, meta_info.iv, ctr_stream_block, metadata_headers.get(), metadata_headers.get()); + aes_crypt_ctr(&aes, metadata_headers.size(), &ctr_nc_off, meta_info.iv, ctr_stream_block, metadata_headers.data(), metadata_headers.data()); // Load the metadata header. - meta_hdr.Load(metadata_headers.get()); + meta_hdr.Load(metadata_headers); // Load the metadata section headers. meta_shdr.clear(); for (unsigned int i = 0; i < meta_hdr.section_count; i++) { + const usz shdr_offset = sizeof(meta_hdr) + sizeof(MetadataSectionHeader) * i; + ensure(metadata_headers.size() > shdr_offset); + meta_shdr.emplace_back(); - meta_shdr.back().Load(metadata_headers.get() + sizeof(meta_hdr) + sizeof(MetadataSectionHeader) * i); + meta_shdr.back().Load(std::span(metadata_headers.data() + shdr_offset, metadata_headers.size() - shdr_offset)); } // Copy the decrypted data keys. - data_keys_length = meta_hdr.key_count * 0x10; - data_keys = std::make_unique(data_keys_length); - memcpy(data_keys.get(), metadata_headers.get() + sizeof(meta_hdr) + meta_hdr.section_count * sizeof(MetadataSectionHeader), data_keys_length); + data_keys.resize(meta_hdr.key_count * 0x10); + + const usz data_keys_offset = sizeof(meta_hdr) + meta_hdr.section_count * sizeof(MetadataSectionHeader); + ensure(metadata_headers.size() >= (data_keys_offset + data_keys.size())); + std::memcpy(data_keys.data(), metadata_headers.data() + data_keys_offset, data_keys.size()); return true; } @@ -1174,6 +1184,7 @@ bool SELFDecrypter::LoadMetadata(const u8* klic_key) bool SELFDecrypter::DecryptData() { aes_context aes; + usz data_buf_length = 0; // Calculate the total data size. for (unsigned int i = 0; i < meta_hdr.section_count; i++) @@ -1186,7 +1197,7 @@ bool SELFDecrypter::DecryptData() } // Allocate a buffer to store decrypted data. - data_buf = std::make_unique(data_buf_length); + data_buf.resize(data_buf_length); // Set initial offset. u32 data_buf_offset = 0; @@ -1206,8 +1217,8 @@ bool SELFDecrypter::DecryptData() if((meta_shdr[i].key_idx <= meta_hdr.key_count - 1) && (meta_shdr[i].iv_idx <= meta_hdr.key_count)) { // Get the key and iv from the previously stored key buffer. - memcpy(data_key, data_keys.get() + meta_shdr[i].key_idx * 0x10, 0x10); - memcpy(data_iv, data_keys.get() + meta_shdr[i].iv_idx * 0x10, 0x10); + std::memcpy(data_key, data_keys.data() + meta_shdr[i].key_idx * 0x10, 0x10); + std::memcpy(data_iv, data_keys.data() + meta_shdr[i].iv_idx * 0x10, 0x10); // Allocate a buffer to hold the data. auto buf = std::make_unique(meta_shdr[i].data_size); @@ -1217,14 +1228,14 @@ bool SELFDecrypter::DecryptData() self_f.read(buf.get(), meta_shdr[i].data_size); // Zero out our ctr nonce. - memset(ctr_stream_block, 0, sizeof(ctr_stream_block)); + std::memset(ctr_stream_block, 0, sizeof(ctr_stream_block)); // Perform AES-CTR encryption on the data blocks. aes_setkey_enc(&aes, data_key, 128); aes_crypt_ctr(&aes, meta_shdr[i].data_size, &ctr_nc_off, data_iv, ctr_stream_block, buf.get(), buf.get()); // Copy the decrypted data. - memcpy(data_buf.get() + data_buf_offset, buf.get(), meta_shdr[i].data_size); + std::memcpy(data_buf.data() + data_buf_offset, buf.get(), meta_shdr[i].data_size); // Advance the buffer's offset. data_buf_offset += ::narrow(meta_shdr[i].data_size); @@ -1255,8 +1266,7 @@ fs::file SELFDecrypter::MakeElf(bool isElf32) bool SELFDecrypter::GetKeyFromRap(const char* content_id, u8* npdrm_key) { // Set empty RAP key. - u8 rap_key[0x10]; - memset(rap_key, 0, 0x10); + std::array rap_key {}; // Try to find a matching RAP file under exdata folder. const std::string ci_str = content_id; @@ -1275,14 +1285,14 @@ bool SELFDecrypter::GetKeyFromRap(const char* content_id, u8* npdrm_key) self_log.notice("Loading RAP file %s.rap", ci_str); - if (rap_file.read(rap_key, 0x10) != 0x10) + if (rap_file.read(rap_key.data(), rap_key.size()) != rap_key.size()) { self_log.fatal("Failed to load %s: RAP file exists but is invalid. Try reinstalling it.", rap_path); return false; } // Convert the RAP key. - rap_to_rif(rap_key, npdrm_key); + rap_to_rif(rap_key.data(), npdrm_key); return true; } @@ -1480,7 +1490,7 @@ bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key, NPD_HEADER* n { if (const NPD_HEADER* npd = self_dec.GetNPDHeader()) { - memcpy(npd_out, npd, sizeof(NPD_HEADER)); + std::memcpy(npd_out, npd, sizeof(NPD_HEADER)); } } } @@ -1512,7 +1522,7 @@ bool get_npdrm_self_header(const fs::file& self, NPD_HEADER &npd_out) if (const NPD_HEADER* npd = self_dec.GetNPDHeader()) { - memcpy(&npd_out, npd, sizeof(NPD_HEADER)); + std::memcpy(&npd_out, npd, sizeof(NPD_HEADER)); return true; } } diff --git a/rpcs3/Crypto/unself.h b/rpcs3/Crypto/unself.h index 1279bc961d..cdda6d3f08 100644 --- a/rpcs3/Crypto/unself.h +++ b/rpcs3/Crypto/unself.h @@ -9,6 +9,8 @@ #include "unedat.h" +#include + LOG_CHANNEL(self_log, "SELF"); // SCE-specific definitions for e_type: @@ -163,7 +165,7 @@ struct MetadataInfo u8 iv[0x10]; u8 iv_pad[0x10]; - void Load(u8* in); + void Load(std::span in); void Show() const; }; @@ -177,7 +179,7 @@ struct MetadataHeader u32 unknown2; u32 unknown3; - void Load(u8* in); + void Load(std::span in); void Show() const; }; @@ -194,7 +196,7 @@ struct MetadataSectionHeader u32 iv_idx; u32 compressed; - void Load(u8* in); + void Load(std::span in); void Show() const; }; @@ -416,13 +418,11 @@ protected: // Metadata structs. MetadataInfo meta_info{}; MetadataHeader meta_hdr{}; - std::vector meta_shdr{}; + std::vector meta_shdr; // Internal data buffers. - std::unique_ptr data_keys{}; - u32 data_keys_length{}; - std::unique_ptr data_buf{}; - u32 data_buf_length{}; + std::vector data_keys; + std::vector data_buf; public: SCEDecrypter(const fs::file& s); @@ -463,10 +463,8 @@ class SELFDecrypter std::vector meta_shdr{}; // Internal data buffers. - std::unique_ptr data_keys{}; - u32 data_keys_length{}; - std::unique_ptr data_buf{}; - u32 data_buf_length{}; + std::vector data_keys; + std::vector data_buf; // Main key vault instance. KeyVault key_v{}; @@ -512,14 +510,13 @@ private: std::unique_ptr decomp_buf(new u8[filesz]); // Create a buffer separate from data_buf to uncompress. - std::unique_ptr zlib_buf(new u8[data_buf_length]); - memcpy(zlib_buf.get(), data_buf.get(), data_buf_length); + std::vector zlib_buf = data_buf; uLongf decomp_buf_length = ::narrow(filesz); // Use zlib uncompress on the new buffer. // decomp_buf_length changes inside the call to uncompress - const int rv = uncompress(decomp_buf.get(), &decomp_buf_length, zlib_buf.get() + data_buf_offset, data_buf_length); + const int rv = uncompress(decomp_buf.get(), &decomp_buf_length, zlib_buf.data() + data_buf_offset, ::size32(zlib_buf)); // Check for errors (TODO: Probably safe to remove this once these changes have passed testing.) switch (rv) @@ -538,7 +535,7 @@ private: { // Seek to the program header data offset and write the data. e.seek(phdr[meta_shdr[i].program_idx].p_offset); - e.write(data_buf.get() + data_buf_offset, meta_shdr[i].data_size); + e.write(data_buf.data() + data_buf_offset, meta_shdr[i].data_size); } // Advance the data buffer offset by data size. diff --git a/rpcs3/Emu/Cell/Modules/cellAdec.cpp b/rpcs3/Emu/Cell/Modules/cellAdec.cpp index 0d0c4481e9..56f292c49d 100644 --- a/rpcs3/Emu/Cell/Modules/cellAdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAdec.cpp @@ -482,7 +482,7 @@ void LpcmDecContext::exec(ppu_thread& ppu) case CELL_ADEC_CH_3_2_LFE: for (s32 i = 0; i < sample_num; i += channel_num) { - const u64 tmp = std::rotl(read_from_ptr(&_output[i + 1]), 0x20); // Swap Front Right and Center + const u64 tmp = std::rotl(read_from_ptr_unsafe(_output, i + 1), 0x20); // Swap Front Right and Center std::memcpy(&_output[i + 1], &tmp, sizeof(u64)); } break; @@ -511,7 +511,7 @@ void LpcmDecContext::exec(ppu_thread& ppu) { const v128 tmp1 = gv_shuffle32<3, 2, 0, 1>(v128::loadu(&_output[i + 4])); // Reorder Rear Left, Rear Right, Side Right, LFE -> LFE, Side Right, Rear Left, Rear Right v128::storeu(tmp1, &_output[i + 4]); - const u64 tmp2 = std::rotl(read_from_ptr(&_output[i + 3]), 0x20); // Swap Side Left and LFE + const u64 tmp2 = std::rotl(read_from_ptr_unsafe(_output, i + 3), 0x20); // Swap Side Left and LFE std::memcpy(&_output[i + 3], &tmp2, sizeof(u64)); } break; @@ -620,8 +620,8 @@ void LpcmDecContext::exec(ppu_thread& ppu) const v128 tmp1 = gv_loadu32(&input_u8[i_in]); const v128 tmp2 = gv_loadu32(&input_u8[i_in + high_bytes_3_4_offset]); v128 s20be = gv_unpacklo32(tmp1, tmp2); - s20be = gv_insert16<4>(s20be, read_from_ptr(&input_u8[i_in + low_bits_1_2_offset])); - s20be = gv_insert16<5>(s20be, read_from_ptr(&input_u8[i_in + low_bits_3_4_offset])); + s20be = gv_insert16<4>(s20be, read_from_ptr_unsafe(input_u8, i_in + low_bits_1_2_offset)); + s20be = gv_insert16<5>(s20be, read_from_ptr_unsafe(input_u8, i_in + low_bits_3_4_offset)); // Reorder bytes to form four 32-bit integer samples v128 _s32 = gv_shuffle8(s20be, shuffle_ctrl); @@ -651,8 +651,8 @@ void LpcmDecContext::exec(ppu_thread& ppu) const v128 tmp1 = gv_loadu32(&input_u8[i_in]); const v128 tmp2 = gv_loadu32(&input_u8[i_in + high_bytes_3_4_offset]); v128 s24be = gv_unpacklo32(tmp1, tmp2); - s24be = gv_insert16<4>(s24be, read_from_ptr(&input_u8[i_in + low_bytes_1_2_offset])); - s24be = gv_insert16<5>(s24be, read_from_ptr(&input_u8[i_in + low_bytes_3_4_offset])); + s24be = gv_insert16<4>(s24be, read_from_ptr_unsafe(input_u8, i_in + low_bytes_1_2_offset)); + s24be = gv_insert16<5>(s24be, read_from_ptr_unsafe(input_u8, i_in + low_bytes_3_4_offset)); // Reorder bytes to form four 32-bit integer samples const v128 _s32 = std::endian::native == std::endian::little diff --git a/rpcs3/Emu/Cell/Modules/cellAtracXdec.cpp b/rpcs3/Emu/Cell/Modules/cellAtracXdec.cpp index fb3191bcb4..21d9c2ace1 100644 --- a/rpcs3/Emu/Cell/Modules/cellAtracXdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAtracXdec.cpp @@ -773,7 +773,7 @@ error_code _CellAdecCoreOpOpenExt_atracx(ppu_thread& ppu, vm::ptr::make(handle.addr() + utils::align(static_cast(sizeof(AtracXdecContext)), 0x80) + ATXDEC_SPURS_STRUCTS_SIZE))); const vm::var mutex_attr{{ SYS_SYNC_PRIORITY, SYS_SYNC_NOT_RECURSIVE, SYS_SYNC_NOT_PROCESS_SHARED, SYS_SYNC_NOT_ADAPTIVE, 0, 0, 0, { "_atd001"_u64 } }}; diff --git a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp index ecf59db508..5fa2672369 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmuxPamf.cpp @@ -309,7 +309,7 @@ u32 dmux_pamf_base::video_stream::parse_stream(std::span stream) // Search for delimiter in cache for (; cache_idx < static_cast(cache.size()); cache_idx++) { - if (const be_t code = read_from_ptr>(buf.data(), cache_idx); + if (const be_t code = read_from_ptr>(buf, cache_idx); (avc && code == AVC_AU_DELIMITER) || (!avc && (code == M2V_PIC_START || code == M2V_SEQUENCE_HEADER || code == M2V_SEQUENCE_END))) { if (current_au.state != access_unit::state::none && (avc || current_au.state != access_unit::state::m2v_sequence)) @@ -335,7 +335,7 @@ u32 dmux_pamf_base::video_stream::parse_stream(std::span stream) // Search for delimiter in stream for (; stream_it <= stream.end() - sizeof(u32); stream_it++) { - if (const be_t code = read_from_ptr>(stream_it); + if (const be_t code = read_from_ptr_unsafe>(stream_it); (avc && code == AVC_AU_DELIMITER) || (!avc && (code == M2V_PIC_START || code == M2V_SEQUENCE_HEADER || code == M2V_SEQUENCE_END))) { if (current_au.state != access_unit::state::none && (avc || current_au.state != access_unit::state::m2v_sequence)) @@ -440,7 +440,7 @@ u32 dmux_pamf_base::audio_stream::parse_stream(std::span stream) // Search for delimiter in cache for (; cache_idx <= static_cast(cache.size() + std::min(sizeof(u16) - 1, stream.size()) - sizeof(u16)); cache_idx++) { - if (const be_t tmp = read_from_ptr>(buf.data(), cache_idx); current_au.size_info_offset != 0) + if (const be_t tmp = read_from_ptr>(buf, cache_idx); current_au.size_info_offset != 0) { if (--current_au.size_info_offset == 0) { @@ -473,7 +473,7 @@ u32 dmux_pamf_base::audio_stream::parse_stream(std::span stream) // Search for delimiter in stream for (; stream_it <= stream.end() - sizeof(u32); stream_it++) // LLE uses sizeof(u32), even though the delimiter is only two bytes large { - if (const be_t tmp = read_from_ptr>(stream_it); current_au.size_info_offset != 0) + if (const be_t tmp = read_from_ptr_unsafe>(stream_it); current_au.size_info_offset != 0) { if (--current_au.size_info_offset == 0) { @@ -524,7 +524,7 @@ u32 dmux_pamf_base::user_data_stream::parse_stream_header(std::span pe return umax; } - au_size_unk = read_from_ptr>(pes_packet_data.begin(), 2) - sizeof(u32); + au_size_unk = read_from_ptr>(pes_packet_data, 2) - sizeof(u32); return 10; } @@ -741,7 +741,7 @@ bool dmux_pamf_base::process_next_pack() // Skip over system header if present if (read_from_ptr>(current_pes_packet) == SYSTEM_HEADER) { - const u32 system_header_length = read_from_ptr>(current_pes_packet.begin(), PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); + const u32 system_header_length = read_from_ptr>(current_pes_packet, PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store if (system_header_length + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8) > current_pes_packet.size()) @@ -766,7 +766,7 @@ bool dmux_pamf_base::process_next_pack() // A system header is optionally followed by a private stream 2 // The first two bytes of the stream are the stream id of a video stream. The next access unit of that stream is a random access point/keyframe - const u16 pes_packet_length = read_from_ptr>(current_pes_packet.begin(), PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); + const u16 pes_packet_length = read_from_ptr>(current_pes_packet, PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store if (pes_packet_length + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8) > current_pes_packet.size()) @@ -775,7 +775,7 @@ bool dmux_pamf_base::process_next_pack() return false; } - if (const u8 channel = read_from_ptr>(current_pes_packet.begin(), PES_PACKET_LENGTH_OFFSET + sizeof(u16)) & 0xf; + if (const u8 channel = read_from_ptr>(current_pes_packet, PES_PACKET_LENGTH_OFFSET + sizeof(u16)) & 0xf; elementary_stream::is_enabled(elementary_streams[0][channel])) { elementary_streams[0][channel]->set_rap(); @@ -796,8 +796,8 @@ bool dmux_pamf_base::process_next_pack() return false; } - const u16 pes_packet_length = read_from_ptr>(current_pes_packet.begin(), PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); - const u8 pes_header_data_length = read_from_ptr(current_pes_packet.begin(), PES_HEADER_DATA_LENGTH_OFFSET) + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8); + const u16 pes_packet_length = read_from_ptr>(current_pes_packet, PES_PACKET_LENGTH_OFFSET) + PES_PACKET_LENGTH_OFFSET + sizeof(u16); + const u8 pes_header_data_length = read_from_ptr(current_pes_packet, PES_HEADER_DATA_LENGTH_OFFSET) + PES_HEADER_DATA_LENGTH_OFFSET + sizeof(u8); // Not checked on LLE, the SPU task would just increment the reading position and read random data in the SPU local store if (pes_packet_length > current_pes_packet.size() || pes_packet_length <= pes_header_data_length) @@ -821,23 +821,23 @@ bool dmux_pamf_base::process_next_pack() if (elementary_stream::is_enabled(elementary_streams[type_idx][channel])) { - const s8 pts_dts_flag = read_from_ptr(current_pes_packet.begin(), PTS_DTS_FLAG_OFFSET); + const s8 pts_dts_flag = read_from_ptr(current_pes_packet, PTS_DTS_FLAG_OFFSET); if (pts_dts_flag < 0) { // The timestamps should be unsigned, but are sign-extended from s32 to u64 on LLE. They probably forgot about integer promotion - const s32 PTS_32_30 = read_from_ptr>(current_pes_packet.begin(), 9); - const s32 PTS_29_15 = read_from_ptr, 1, 15>>(current_pes_packet.begin(), 10); - const s32 PTS_14_0 = read_from_ptr, 1, 15>>(current_pes_packet.begin(), 12); + const s32 PTS_32_30 = read_from_ptr>(current_pes_packet, 9); + const s32 PTS_29_15 = read_from_ptr, 1, 15>>(current_pes_packet, 10); + const s32 PTS_14_0 = read_from_ptr, 1, 15>>(current_pes_packet, 12); elementary_streams[type_idx][channel]->set_pts(PTS_32_30 << 30 | PTS_29_15 << 15 | PTS_14_0); // Bit 32 is discarded } if (pts_dts_flag & 0x40) { - const s32 DTS_32_30 = read_from_ptr>(current_pes_packet.begin(), 14); - const s32 DTS_29_15 = read_from_ptr, 1, 15>>(current_pes_packet.begin(), 15); - const s32 DTS_14_0 = read_from_ptr, 1, 15>>(current_pes_packet.begin(), 17); + const s32 DTS_32_30 = read_from_ptr>(current_pes_packet, 14); + const s32 DTS_29_15 = read_from_ptr, 1, 15>>(current_pes_packet, 15); + const s32 DTS_14_0 = read_from_ptr, 1, 15>>(current_pes_packet, 17); elementary_streams[type_idx][channel]->set_dts(DTS_32_30 << 30 | DTS_29_15 << 15 | DTS_14_0); // Bit 32 is discarded } diff --git a/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp b/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp index 75f0f5d2a9..e92298d675 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp @@ -366,7 +366,7 @@ template const vm::var boot_flag(8); std::memset(boot_flag.get_ptr(), 0, boot_flag.get_count()); - if (ret != CELL_OK || !read_from_ptr>(paramsfo.get_ptr(), 0x18)) + if (ret != CELL_OK || !read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x18)) { const vm::var file_descriptor; @@ -379,15 +379,15 @@ template ensure(sys_fs_read(ppu, *file_descriptor, boot_flag, 8, nread) == CELL_OK && *nread == 8ull); // Not checked on LLE ensure(sys_fs_close(ppu, *file_descriptor) == CELL_OK); // Not checked on LLE - return !!read_from_ptr>(boot_flag.get_ptr(), 1); + return !!read_from_ptr_unsafe>(boot_flag.get_ptr(), 1); } - return !read_from_ptr>(paramsfo.get_ptr(), 0x10); + return !read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x10); } case CELL_SYSMODULE_GCM_SYS: { // If the extra load flag "EnableGCMDebug" is set, loads libgcm_sys_deh.sprx instead of libgcm_sys.sprx - return ret != CELL_OK || !read_from_ptr>(paramsfo.get_ptr(), 0x10); + return ret != CELL_OK || !read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x10); } case CELL_SYSMODULE_FS: { @@ -579,7 +579,7 @@ extern error_code sysmoduleModuleStart(ppu_thread& ppu, u32 args, vm::ptr { if (module_id == CELL_SYSMODULE_GCM_SYS) { - if (get_paramsfo_ret == CELL_OK && read_from_ptr>(paramsfo.get_ptr(), 0x10) && !retail_gcm_sys) + if (get_paramsfo_ret == CELL_OK && read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x10) && !retail_gcm_sys) { if (load_module(ppu, GCM_SYS_DEH_IDX, 8, paramsfo + 0x28) != CELL_OK) { @@ -641,7 +641,7 @@ extern error_code sysmoduleModuleStart(ppu_thread& ppu, u32 args, vm::ptr // Start the modules for (const auto [module_id, prx_ix] : std::views::zip(DEFAULT_MODULES, std::span{ id_list.begin().get_ptr(), id_list.get_count() })) { - if (module_id == CELL_SYSMODULE_GCM_SYS && read_from_ptr>(paramsfo.get_ptr(), 0x10) && !retail_gcm_sys) + if (module_id == CELL_SYSMODULE_GCM_SYS && read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x10) && !retail_gcm_sys) { s_sysmodule_context->module_states[CELL_SYSMODULE_GCM_SYS].prx_id = static_cast(prx_ix); @@ -691,7 +691,7 @@ extern error_code sysmoduleModuleStart(ppu_thread& ppu, u32 args, vm::ptr // Load additional modules if certain ExtraLoadFlags are set - if (read_from_ptr>(paramsfo.get_ptr(), 0x10) && !retail_gcm_sys && read_from_ptr>(paramsfo.get_ptr(), 0x18)) + if (read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x10) && !retail_gcm_sys && read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x18)) { cellSysmoduleSetDebugmode(true); @@ -703,7 +703,7 @@ extern error_code sysmoduleModuleStart(ppu_thread& ppu, u32 args, vm::ptr cellSysmoduleSetDebugmode(false); } - if (read_from_ptr>(paramsfo.get_ptr(), 0x10) && read_from_ptr>(paramsfo.get_ptr(), 0x18)) + if (read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x10) && read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x18)) { if (load_module(ppu, PROF_IDX, 0, vm::null) != CELL_OK) { @@ -711,7 +711,7 @@ extern error_code sysmoduleModuleStart(ppu_thread& ppu, u32 args, vm::ptr } } - if (read_from_ptr>(paramsfo.get_ptr(), 0x10)) + if (read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x10)) { if (load_module(ppu, LV2COREDUMP_IDX, 0, vm::null) != CELL_OK) { @@ -719,7 +719,7 @@ extern error_code sysmoduleModuleStart(ppu_thread& ppu, u32 args, vm::ptr } } - if (read_from_ptr>(paramsfo.get_ptr(), 0x10)) + if (read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x10)) { if (cellSysmoduleLoadModuleInternal(ppu, 0xf022) != CELL_OK) { @@ -1152,7 +1152,7 @@ error_code cellSysmoduleLoadModuleInternal(ppu_thread& ppu, u16 id) std::memset(paramsfo.get_ptr(), 0, paramsfo.get_count()); if (ppu_execute<&sys_process_get_paramsfo>(ppu, +paramsfo) != CELL_OK - || (!read_from_ptr>(paramsfo.get_ptr(), 0x18) && !read_from_ptr>(paramsfo.get_ptr(), 0x30))) + || (!read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x18) && !read_from_ptr_unsafe>(paramsfo.get_ptr(), 0x30))) { return CELL_SYSMODULE_ERROR_UNKNOWN; } diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index ac0557cefe..56806f9898 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -480,7 +480,7 @@ static inline u8* ppu_seg_ptr(u32 addr) static inline ppu_intrp_func_t ppu_read(u32 addr) { - return read_from_ptr(ppu_ptr(addr)); + return read_from_ptr_unsafe(ppu_ptr(addr)); } // Get interpreter cache value @@ -505,7 +505,7 @@ static void ppu_fallback(ppu_thread& ppu, ppu_opcode_t op, be_t* this_op, p { const auto _pc = vm::get_addr(this_op); const auto _fn = ppu_cache(_pc); - write_to_ptr(ppu_ptr(_pc), _fn); + write_to_ptr_unsafe(ppu_ptr(_pc), _fn); return _fn(ppu, op, this_op, next_fn); } @@ -590,7 +590,7 @@ u32 ppu_read_mmio_aware_u32(u8* vm_base, u32 eal) } // Value is assumed to be swapped - return read_from_ptr(vm_base, eal); + return read_from_ptr_unsafe(vm_base, eal); } void ppu_write_mmio_aware_u32(u8* vm_base, u32 eal, u32 value) @@ -618,7 +618,7 @@ void ppu_write_mmio_aware_u32(u8* vm_base, u32 eal, u32 value) } // Value is assumed swapped - write_to_ptr(vm_base + eal, value); + write_to_ptr_unsafe(vm_base + eal, value); } extern bool ppu_test_address_may_be_mmio(std::span> insts) @@ -793,13 +793,13 @@ extern void ppu_register_range(u32 addr, u32 size) if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm) { // Assume addr is the start of first segment of PRX - write_to_ptr(ppu_ptr(addr), std::bit_cast(ppu_recompiler_fallback_ghc)); - write_to_ptr(ppu_seg_ptr(addr), static_cast(seg_base >> 13)); + write_to_ptr_unsafe(ppu_ptr(addr), std::bit_cast(ppu_recompiler_fallback_ghc)); + write_to_ptr_unsafe(ppu_seg_ptr(addr), static_cast(seg_base >> 13)); } else { - write_to_ptr(ppu_ptr(addr), ppu_fallback); - write_to_ptr(ppu_seg_ptr(addr), 0); + write_to_ptr_unsafe(ppu_ptr(addr), ppu_fallback); + write_to_ptr_unsafe(ppu_seg_ptr(addr), 0); } addr += 4; @@ -814,7 +814,7 @@ extern void ppu_register_function_at(u32 addr, u32 size, ppu_intrp_func_t ptr = // Initialize specific function if (ptr) { - write_to_ptr(ppu_ptr(addr), std::bit_cast(ptr)); + write_to_ptr_unsafe(ppu_ptr(addr), std::bit_cast(ptr)); return; } @@ -841,7 +841,7 @@ extern void ppu_register_function_at(u32 addr, u32 size, ppu_intrp_func_t ptr = { if (auto old = ppu_read(addr); old != ppu_break && old != ppu_far_jump) { - write_to_ptr(ppu_ptr(addr), ppu_cache(addr)); + write_to_ptr_unsafe(ppu_ptr(addr), ppu_cache(addr)); } addr += 4; @@ -1270,7 +1270,7 @@ extern bool ppu_breakpoint(u32 addr, bool is_adding) return false; } - write_to_ptr(ppu_ptr(addr), breakpoint); + write_to_ptr_unsafe(ppu_ptr(addr), breakpoint); return true; } @@ -1279,7 +1279,7 @@ extern bool ppu_breakpoint(u32 addr, bool is_adding) return false; } - write_to_ptr(ppu_ptr(addr), func_original); + write_to_ptr_unsafe(ppu_ptr(addr), func_original); return true; } @@ -1314,7 +1314,7 @@ extern bool ppu_patch(u32 addr, u32 value) { if (auto old = ppu_read(addr); old != ppu_break && old != ppu_fallback) { - write_to_ptr(ppu_ptr(addr), ppu_cache(addr)); + write_to_ptr_unsafe(ppu_ptr(addr), ppu_cache(addr)); } } @@ -3979,7 +3979,7 @@ extern void ppu_precompile(std::vector& dir_queue, std::vectorget_ptr(static_cast(constant_value), 16)) { // Try to read from that address - if (const u128 klic_value = read_from_ptr(klic_ptr)) + if (const u128 klic_value = read_from_ptr_unsafe(klic_ptr)) { if (!std::count_if(decrypt_klics.begin(), decrypt_klics.end(), FN(std::memcmp(&x, &klic_value, 16) == 0))) { @@ -4537,7 +4537,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_s if (g_cfg.core.ppu_debug && func.size && func.toc != umax && !ppu_get_far_jump(func.addr)) { ppu_toc[func.addr] = func.toc; - write_to_ptr(ppu_ptr(func.addr), &ppu_check_toc); + write_to_ptr_unsafe(ppu_ptr(func.addr), &ppu_check_toc); } } @@ -4736,7 +4736,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_s [[maybe_unused]] auto write_le = [](u8*& code, auto value) { - write_to_ptr>>(code, value); + write_to_ptr_unsafe>>(code, value); code += sizeof(value); }; @@ -5559,7 +5559,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_s { if (*inst_ptr == ppu_instructions::BLR() && reinterpret_cast(ppu_read(addr)) == reinterpret_cast(ppu_recompiler_fallback_ghc)) { - write_to_ptr(ppu_ptr(addr), BLR_func); + write_to_ptr_unsafe(ppu_ptr(addr), BLR_func); } } } diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index dee3f15309..31bf027e06 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -7235,7 +7235,7 @@ s64 spu_channel::pop_wait(cpu_thread& spu, bool pop) while (true) { const usz is_le = std::endian::native == std::endian::little ? 1 : 0; - thread_ctrl::wait_on(utils::bless>(&data)[is_le], read_from_ptr(reinterpret_cast(&old), is_le * 4)); + thread_ctrl::wait_on(utils::bless>(&data)[is_le], read_from_ptr_unsafe(reinterpret_cast(&old), is_le * 4)); old = data; diff --git a/rpcs3/Emu/Cell/lv2/sys_game.cpp b/rpcs3/Emu/Cell/lv2/sys_game.cpp index 1164dbd216..db2bbe49e9 100644 --- a/rpcs3/Emu/Cell/lv2/sys_game.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_game.cpp @@ -48,12 +48,12 @@ public: return true; } - bool write(u8* buffer) + bool write(const u8* buffer) { if (!buffer) return false; - storage.store(read_from_ptr>(buffer)); + storage.store(read_from_ptr_unsafe>(buffer)); written = true; return true; diff --git a/rpcs3/Emu/Io/Dimensions.cpp b/rpcs3/Emu/Io/Dimensions.cpp index 179be8ef3c..0cbcf6be8d 100644 --- a/rpcs3/Emu/Io/Dimensions.cpp +++ b/rpcs3/Emu/Io/Dimensions.cpp @@ -96,8 +96,8 @@ u32 dimensions_toypad::get_next() std::array dimensions_toypad::decrypt(const u8* buf, std::optional> key) { // Value to decrypt is separated in to two little endian 32 bit unsigned integers - u32 data_one = read_from_ptr>(buf); - u32 data_two = read_from_ptr>(buf, 4); + u32 data_one = read_from_ptr_unsafe>(buf); + u32 data_two = read_from_ptr_unsafe>(buf, 4); // Use the key as 4 32 bit little endian unsigned integers u32 key_one; @@ -143,8 +143,8 @@ std::array dimensions_toypad::encrypt(const u8* buf, std::optional>(buf); - u32 data_two = read_from_ptr>(buf, 4); + u32 data_one = read_from_ptr_unsafe>(buf); + u32 data_two = read_from_ptr_unsafe>(buf, 4); // Use the key as 4 32 bit little endian unsigned integers u32 key_one; @@ -328,7 +328,7 @@ void dimensions_toypad::write_block(u8 index, u8 page, const u8* to_write_buf, s // Id is written to page 36 if (page == 36) { - figure.id = read_from_ptr>(to_write_buf); + figure.id = read_from_ptr_unsafe>(to_write_buf); } std::memcpy(figure.data.data() + (page * 4), to_write_buf, 4); figure.save(); diff --git a/rpcs3/Emu/Io/Skylander.cpp b/rpcs3/Emu/Io/Skylander.cpp index 974e9a887f..9cb909edf1 100644 --- a/rpcs3/Emu/Io/Skylander.cpp +++ b/rpcs3/Emu/Io/Skylander.cpp @@ -91,7 +91,7 @@ void sky_portal::get_status(u8* reply_buf) std::memset(reply_buf, 0, 0x20); reply_buf[0] = 0x53; - write_to_ptr>(reply_buf, 1, status); + write_to_ptr_unsafe>(reply_buf, 1, status); reply_buf[5] = interrupt_counter++; reply_buf[6] = 0x01; } @@ -153,11 +153,11 @@ bool sky_portal::remove_skylander(u8 sky_num) return false; } -u8 sky_portal::load_skylander(u8* buf, fs::file in_file) +u8 sky_portal::load_skylander(const std::array& data, fs::file in_file) { std::lock_guard lock(sky_mutex); - const u32 sky_serial = read_from_ptr>(buf); + const u32 sky_serial = read_from_ptr>(data); u8 found_slot = 0xFF; // mimics spot retaining on the portal @@ -181,7 +181,7 @@ u8 sky_portal::load_skylander(u8* buf, fs::file in_file) ensure(found_slot != 0xFF); skylander& thesky = skylanders[found_slot]; - memcpy(thesky.data.data(), buf, thesky.data.size()); + memcpy(thesky.data.data(), data.data(), thesky.data.size()); thesky.sky_file = std::move(in_file); thesky.status = 3; thesky.queued_status.push(3); diff --git a/rpcs3/Emu/Io/Skylander.h b/rpcs3/Emu/Io/Skylander.h index be67c8c3cc..0522f18064 100644 --- a/rpcs3/Emu/Io/Skylander.h +++ b/rpcs3/Emu/Io/Skylander.h @@ -2,6 +2,7 @@ #include "Emu/Io/usb_device.h" #include "Utilities/mutex.h" +#include #include struct skylander @@ -26,7 +27,7 @@ public: void write_block(u8 sky_num, u8 block, const u8* to_write_buf, u8* reply_buf); bool remove_skylander(u8 sky_num); - u8 load_skylander(u8* buf, fs::file in_file); + u8 load_skylander(const std::array& data, fs::file in_file); protected: shared_mutex sky_mutex; diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index e1f0561b7c..c01263e4bd 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -1700,8 +1700,8 @@ namespace vm for (usz i = 0; i < byte_of_pages; i += 128 * 2) { - const u64 sample64_1 = read_from_ptr(data_ptr, i); - const u64 sample64_2 = read_from_ptr(data_ptr, i + 128); + const u64 sample64_1 = read_from_ptr_unsafe(data_ptr, i); + const u64 sample64_2 = read_from_ptr_unsafe(data_ptr, i + 128); // Speed up testing in scenarios where it is likely non-zero data if (sample64_1 && sample64_2) diff --git a/rpcs3/Emu/NP/np_handler.cpp b/rpcs3/Emu/NP/np_handler.cpp index df67c47990..05c4d626f1 100644 --- a/rpcs3/Emu/NP/np_handler.cpp +++ b/rpcs3/Emu/NP/np_handler.cpp @@ -116,7 +116,7 @@ namespace np parse(); } - std::size_t ticket::size() const + usz ticket::size() const { return raw_data.size(); } @@ -258,7 +258,7 @@ namespace np return std::string(vec.begin(), it); } - std::optional ticket::parse_node(std::size_t index) const + std::optional ticket::parse_node(usz index) const { if ((index + MIN_TICKET_DATA_SIZE) > size()) { @@ -268,11 +268,11 @@ namespace np ticket_data tdata{}; const auto* ptr = data() + index; - tdata.id = read_from_ptr>(ptr); - tdata.len = read_from_ptr>(ptr + 2); - const auto* data_ptr = data() + index + 4; + tdata.id = read_from_ptr_unsafe>(ptr); + tdata.len = read_from_ptr_unsafe>(ptr, 2); + const usz data_offset = index + 4; - auto check_size = [&](std::size_t expected) -> bool + auto check_size = [&](usz expected) -> bool { if ((index + MIN_TICKET_DATA_SIZE + expected) > size()) { @@ -294,7 +294,7 @@ namespace np { return std::nullopt; } - tdata.data.data_u32 = read_from_ptr>(data_ptr); + tdata.data.data_u32 = read_from_ptr_unsafe>(data(), data_offset); break; case 2: case 7: @@ -302,7 +302,7 @@ namespace np { return std::nullopt; } - tdata.data.data_u64 = read_from_ptr>(data_ptr); + tdata.data.data_u64 = read_from_ptr_unsafe>(data(), data_offset); break; case 4: case 8: @@ -311,7 +311,7 @@ namespace np return std::nullopt; } tdata.data.data_vec = std::vector(tdata.len); - memcpy(tdata.data.data_vec.data(), data_ptr, tdata.len); + memcpy(tdata.data.data_vec.data(), data() + data_offset, tdata.len); break; default: if ((tdata.id & 0x3000) == 0x3000) @@ -321,7 +321,7 @@ namespace np return std::nullopt; } - std::size_t sub_index = 0; + usz sub_index = 0; tdata.data.data_nodes = {}; while (sub_index < tdata.len) { @@ -352,14 +352,14 @@ namespace np return; } - version = read_from_ptr>(data()); + version = read_from_ptr_unsafe>(data()); if (version != 0x21010000) { ticket_log.error("Invalid version: 0x%08x", version); return; } - u32 given_size = read_from_ptr>(data(), 4); + u32 given_size = read_from_ptr_unsafe>(data(), 4); if ((given_size + 8) != size()) { ticket_log.error("Size mismatch (gs: %d vs s: %d)", given_size, size()); diff --git a/rpcs3/Emu/NP/np_handler.h b/rpcs3/Emu/NP/np_handler.h index 940ad6eac3..c4452675e2 100644 --- a/rpcs3/Emu/NP/np_handler.h +++ b/rpcs3/Emu/NP/np_handler.h @@ -65,7 +65,7 @@ namespace np ticket() = default; ticket(std::vector&& raw_data); - std::size_t size() const; + usz size() const; const u8* data() const; bool empty() const; @@ -73,11 +73,11 @@ namespace np std::string get_service_id() const; private: - std::optional parse_node(std::size_t index) const; + std::optional parse_node(usz index) const; void parse(); private: - static constexpr std::size_t MIN_TICKET_DATA_SIZE = 4; + static constexpr usz MIN_TICKET_DATA_SIZE = 4; std::vector raw_data; diff --git a/rpcs3/Emu/RSX/Common/surface_store.h b/rpcs3/Emu/RSX/Common/surface_store.h index 7dce727402..5289b7b8d7 100644 --- a/rpcs3/Emu/RSX/Common/surface_store.h +++ b/rpcs3/Emu/RSX/Common/surface_store.h @@ -713,50 +713,49 @@ namespace rsx u32 removed_count = 0; - auto compare_and_tag_row = [&](const u32 offset, u32 length) -> bool + auto compare_and_tag_row = [&](u32 offset, u32 length) -> bool { u64 mask = 0; - u8* dst_ptr = marker.data() + offset; while (length >= 8) { - const u64 value = read_from_ptr(dst_ptr); + const u64 value = read_from_ptr(marker, offset); const u64 block_mask = ~value; // If the value is not all 1s, set valid to true mask |= block_mask; - write_to_ptr(dst_ptr, umax); + write_to_ptr(marker, offset, umax); - dst_ptr += 8; + offset += 8; length -= 8; } if (length >= 4) { - const u32 value = read_from_ptr(dst_ptr); + const u32 value = read_from_ptr(marker, offset); const u32 block_mask = ~value; mask |= block_mask; - write_to_ptr(dst_ptr, umax); + write_to_ptr(marker, offset, umax); - dst_ptr += 4; + offset += 4; length -= 4; } if (length >= 2) { - const u16 value = read_from_ptr(dst_ptr); + const u16 value = read_from_ptr(marker, offset); const u16 block_mask = ~value; mask |= block_mask; - write_to_ptr(dst_ptr, umax); + write_to_ptr(marker, offset, umax); - dst_ptr += 2; + offset += 2; length -= 2; } if (length) { - const u8 value = *dst_ptr; + const u8 value = read_from_ptr(marker, offset); const u8 block_mask = ~value; mask |= block_mask; - *dst_ptr = umax; + write_to_ptr(marker, offset, umax); } return !!mask; diff --git a/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp b/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp index fb64f6870f..cf74741772 100644 --- a/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp +++ b/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp @@ -187,7 +187,7 @@ namespace rsx const u64 src_op2_2 = read_from_ptr>(fifo_span, second_index_off); // Fast comparison - if (src_op1_2 != read_from_ptr(out_ptr, first_index_off) || src_op2_2 != read_from_ptr(out_ptr, second_index_off)) + if (src_op1_2 != read_from_ptr_unsafe(out_ptr, first_index_off) || src_op2_2 != read_from_ptr_unsafe(out_ptr, second_index_off)) { to_set_dirty = rsx::pipeline_state::vertex_program_ucode_dirty; } diff --git a/rpcs3/Emu/RSX/RSXFIFO.cpp b/rpcs3/Emu/RSX/RSXFIFO.cpp index 76241ac2de..8dfc435393 100644 --- a/rpcs3/Emu/RSX/RSXFIFO.cpp +++ b/rpcs3/Emu/RSX/RSXFIFO.cpp @@ -202,7 +202,7 @@ namespace rsx } } - const auto ret = read_from_ptr>(+m_cache[0], addr - m_cache_addr); + const auto ret = read_from_ptr_unsafe>(+m_cache[0], addr - m_cache_addr); return {true, ret}; } diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index a2435dcffe..7f42689cb4 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -393,13 +393,13 @@ namespace rsx _max_index = 0; - auto re_evaluate = [&] (const std::byte* ptr, T) + const auto re_evaluate = [&] (const std::byte* ptr, T) { const u64 restart = rsx::method_registers.restart_index_enabled() ? rsx::method_registers.restart_index() : u64{umax}; for (u32 _index = first; _index < first + count; _index++) { - const auto value = read_from_ptr>(ptr, _index * sizeof(T)); + const auto value = read_from_ptr_unsafe>(ptr, _index * sizeof(T)); if (value == restart) { diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index e86006ee89..4fb299561c 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -4013,7 +4013,7 @@ void Emulator::Kill(bool allow_autoexit, bool savestate, savestate_stage* save_s continue; } - const u64 hash_val = read_from_ptr>(result.data) & -65536; + const u64 hash_val = read_from_ptr_unsafe>(result.data) & -65536; const f64 usage = get_cpu_program_usage_percent(hash_val); if (usage == 0) diff --git a/rpcs3/Loader/TAR.cpp b/rpcs3/Loader/TAR.cpp index 5891f0e51e..2af82cf2bc 100644 --- a/rpcs3/Loader/TAR.cpp +++ b/rpcs3/Loader/TAR.cpp @@ -139,7 +139,7 @@ std::unique_ptr tar_object::get_file(const std::string& path, std } else { - tar_log.notice("tar_object::get_file() failed to parse header: offset=0x%x, filesize=0x%x, header_first16=0x%016x", offset, max_size, read_from_ptr>(reinterpret_cast(&header))); + tar_log.notice("tar_object::get_file() failed to parse header: offset=0x%x, filesize=0x%x, header_first16=0x%016x", offset, max_size, read_from_ptr_unsafe>(reinterpret_cast(&header))); } return { size, {} }; diff --git a/rpcs3/rpcs3qt/memory_viewer_panel.cpp b/rpcs3/rpcs3qt/memory_viewer_panel.cpp index 0c779a9558..7026a334ed 100644 --- a/rpcs3/rpcs3qt/memory_viewer_panel.cpp +++ b/rpcs3/rpcs3qt/memory_viewer_panel.cpp @@ -865,7 +865,7 @@ void memory_viewer_panel::ShowMemory() if (const auto ptr = this->to_ptr(addr)) { - const be_t rmem = read_from_ptr>(static_cast(ptr)); + const be_t rmem = read_from_ptr_unsafe>(static_cast(ptr)); t_mem_hex_str += QString::fromStdString(fmt::format("%02x %02x %02x %02x", static_cast(rmem >> 24), static_cast(rmem >> 16), diff --git a/rpcs3/rpcs3qt/skylander_dialog.cpp b/rpcs3/rpcs3qt/skylander_dialog.cpp index 6623d27f03..9c459ea837 100644 --- a/rpcs3/rpcs3qt/skylander_dialog.cpp +++ b/rpcs3/rpcs3qt/skylander_dialog.cpp @@ -640,19 +640,18 @@ skylander_creator_dialog::skylander_creator_dialog(QWidget* parent) } std::array buf{}; - const auto data = buf.data(); // Set the block permissions - write_to_ptr>(data, 0x36, 0x690F0F0F); + write_to_ptr>(buf, 0x36, 0x690F0F0F); for (u32 index = 1; index < 0x10; index++) { - write_to_ptr>(data, (index * 0x40) + 0x36, 0x69080F7F); + write_to_ptr>(buf, (index * 0x40) + 0x36, 0x69080F7F); } // Set the skylander infos - write_to_ptr>(data, (sky_id | sky_var) + 1); - write_to_ptr>(data, 0x10, sky_id); - write_to_ptr>(data, 0x1C, sky_var); + write_to_ptr>(buf, (sky_id | sky_var) + 1); + write_to_ptr>(buf, 0x10, sky_id); + write_to_ptr>(buf, 0x1C, sky_var); // Set checksum - write_to_ptr>(data, 0x1E, skylander_crc16(0xFFFF, data, 0x1E)); + write_to_ptr>(buf, 0x1E, skylander_crc16(0xFFFF, buf.data(), 0x1E)); sky_file.write(buf.data(), buf.size()); sky_file.close(); @@ -796,10 +795,10 @@ void skylander_dialog::load_skylander_path(u8 slot, const QString& path) clear_skylander(slot); - u16 sky_id = reinterpret_cast&>(data[0x10]); - u16 sky_var = reinterpret_cast&>(data[0x1C]); + const u16 sky_id = reinterpret_cast&>(data[0x10]); + const u16 sky_var = reinterpret_cast&>(data[0x1C]); - u8 portal_slot = g_skyportal.load_skylander(data.data(), std::move(sky_file)); + const u8 portal_slot = g_skyportal.load_skylander(data, std::move(sky_file)); sky_slots[slot] = std::tuple(portal_slot, sky_id, sky_var); update_edits(); diff --git a/rpcs3/tests/test_types_util.cpp b/rpcs3/tests/test_types_util.cpp index 8f9251e0a5..37bd5683f5 100644 --- a/rpcs3/tests/test_types_util.cpp +++ b/rpcs3/tests/test_types_util.cpp @@ -77,7 +77,6 @@ namespace utils // write_to_ptr and read_from_ptr with pos std::array arr32_2{}; - std::memset(arr32_2.data(), 0, arr32_2.size() * sizeof(u32)); for (u32 i = 0; i < arr32_2.size() * sizeof(u32); i += sizeof(u32)) { const usz index = i / sizeof(u32); @@ -86,7 +85,7 @@ namespace utils EXPECT_EQ(read_from_ptr(arr32_2, index), i); } - std::memset(arr32_2.data(), 0, arr32_2.size() * sizeof(u32)); + arr32_2 = {}; for (u64 i = 0; i < arr32_2.size() * sizeof(u32); i += sizeof(u64)) { const usz index = i / sizeof(u64); @@ -95,7 +94,7 @@ namespace utils EXPECT_EQ(read_from_ptr(arr32_2, index), i); } - std::memset(arr32_2.data(), 0, arr32_2.size() * sizeof(u32)); + arr32_2 = {}; for (usz i = 0; i < arr32_2.size() * sizeof(u32); i += sizeof(u128)) { const usz index = i / sizeof(u128); @@ -252,7 +251,7 @@ namespace utils #endif } - TEST(Utils, read_write_to_ptr_raw_array) + TEST(Utils, read_write_to_ptr_unsafe) { g_headless = true; // Disable exception popups @@ -261,13 +260,13 @@ namespace utils u8* arr = new u8[arr_size]; std::memset(arr, 0, arr_size); - write_to_ptr(arr, u8(umax)); + write_to_ptr_unsafe(arr, u8(umax)); EXPECT_EQ(*arr, u8(umax)); - write_to_ptr(arr, u16(umax)); + write_to_ptr_unsafe(arr, u16(umax)); EXPECT_EQ(*utils::bless(arr), u16(umax)); - write_to_ptr(arr, u32(umax)); + write_to_ptr_unsafe(arr, u32(umax)); EXPECT_EQ(*utils::bless(arr), u32(umax)); - write_to_ptr(arr, u64(umax)); + write_to_ptr_unsafe(arr, u64(umax)); EXPECT_EQ(*utils::bless(arr), u64(umax)); // write_to_ptr and read_from_ptr with pos @@ -277,42 +276,42 @@ namespace utils std::memset(arr2, 0, arr2_size); for (u8 i = 0; i < arr2_size; i++) { - write_to_ptr(arr2, i, i); + write_to_ptr_unsafe(arr2, i, i); EXPECT_EQ(arr2[i], i); - EXPECT_EQ(read_from_ptr(arr2, i), i); + EXPECT_EQ(read_from_ptr_unsafe(arr2, i), i); } std::memset(arr2, 0, arr2_size); for (u16 i = 0; i < arr2_size; i += sizeof(u16)) { - write_to_ptr(arr2, i, i); + write_to_ptr_unsafe(arr2, i, i); EXPECT_EQ(*utils::bless(arr2 + i), i); - EXPECT_EQ(read_from_ptr(arr2, i), i); + EXPECT_EQ(read_from_ptr_unsafe(arr2, i), i); } std::memset(arr2, 0, arr2_size); for (u32 i = 0; i < arr2_size; i += sizeof(u32)) { - write_to_ptr(arr2, i, i); + write_to_ptr_unsafe(arr2, i, i); EXPECT_EQ(*utils::bless(arr2 + i), i); - EXPECT_EQ(read_from_ptr(arr2, i), i); + EXPECT_EQ(read_from_ptr_unsafe(arr2, i), i); } std::memset(arr2, 0, arr2_size); for (usz i = 0; i < arr2_size; i += sizeof(u64)) { - write_to_ptr(arr2, i, u64(i)); + write_to_ptr_unsafe(arr2, i, u64(i)); EXPECT_EQ(*utils::bless(arr2 + i), i); - EXPECT_EQ(read_from_ptr(arr2, i), i); + EXPECT_EQ(read_from_ptr_unsafe(arr2, i), i); } std::memset(arr2, 0, arr2_size); for (usz i = 0; i < arr2_size; i += sizeof(u128)) { - write_to_ptr(arr2, i, u128(i)); + write_to_ptr_unsafe(arr2, i, u128(i)); const u128 exp_u128 = i; EXPECT_EQ(std::memcmp(arr2, &exp_u128, sizeof(u128)), 0); - const u128 val_u128 = read_from_ptr(arr2, i); + const u128 val_u128 = read_from_ptr_unsafe(arr2, i); EXPECT_EQ(std::memcmp(&val_u128, &exp_u128, sizeof(u128)), 0); } @@ -322,9 +321,9 @@ namespace utils u32* arr32 = new u32[arr32_count]; std::memset(arr32, 0, arr32_size); - write_to_ptr(arr32, u32(umax)); + write_to_ptr_unsafe(arr32, u32(umax)); EXPECT_EQ(*utils::bless(arr32), u32(umax)); - write_to_ptr(arr32, u64(umax)); + write_to_ptr_unsafe(arr32, u64(umax)); EXPECT_EQ(*utils::bless(arr32), u64(umax)); // write_to_ptr and read_from_ptr with pos @@ -336,57 +335,31 @@ namespace utils for (u32 i = 0; i < arr32_2_size; i += sizeof(u32)) { const usz index = i / sizeof(u32); - write_to_ptr(arr32_2, index, i); + write_to_ptr_unsafe(arr32_2, index, i); EXPECT_EQ(*utils::bless(arr32_2 + index), i); - EXPECT_EQ(read_from_ptr(arr32_2, index), i); + EXPECT_EQ(read_from_ptr_unsafe(arr32_2, index), i); } std::memset(arr32_2, 0, arr32_2_size); for (u64 i = 0; i < arr32_2_size; i += sizeof(u64)) { const usz index = i / sizeof(u64); - write_to_ptr(arr32_2, index, i); + write_to_ptr_unsafe(arr32_2, index, i); EXPECT_EQ(*utils::bless(arr32_2 + index), i); - EXPECT_EQ(read_from_ptr(arr32_2, index), i); + EXPECT_EQ(read_from_ptr_unsafe(arr32_2, index), i); } std::memset(arr32_2, 0, arr32_2_size); for (usz i = 0; i < arr32_2_size; i += sizeof(u128)) { const usz index = i / sizeof(u128); - write_to_ptr(arr32_2, index, u128(i)); + write_to_ptr_unsafe(arr32_2, index, u128(i)); const u128 exp_u128 = i; EXPECT_EQ(std::memcmp(arr32_2, &exp_u128, sizeof(u128)), 0); - const u128 val_u128 = read_from_ptr(arr32_2, index); + const u128 val_u128 = read_from_ptr_unsafe(arr32_2, index); EXPECT_EQ(std::memcmp(&val_u128, &exp_u128, sizeof(u128)), 0); } - // There are no sanity checks for raw pointers in these functions, so these will not fail. -#if 0 - // These tests can take a long time and produce warnings, so let's only run them in local builds -#if CHECK_DEATH - EXPECT_DEATH(write_to_ptr(arr, u128()), ".*"); - EXPECT_DEATH(write_to_ptr(arr2, arr2_size, u8()), ".*"); - EXPECT_DEATH(write_to_ptr(arr2, arr2_size, u16()), ".*"); - EXPECT_DEATH(write_to_ptr(arr2, arr2_size, u32()), ".*"); - EXPECT_DEATH(write_to_ptr(arr2, arr2_size, u64()), ".*"); - EXPECT_DEATH(write_to_ptr(arr2, arr2_size, u128()), ".*"); - EXPECT_DEATH(read_from_ptr(arr2, arr2_size), ".*"); - EXPECT_DEATH(read_from_ptr(arr2, arr2_size), ".*"); - EXPECT_DEATH(read_from_ptr(arr2, arr2_size), ".*"); - EXPECT_DEATH(read_from_ptr(arr2, arr2_size), ".*"); - EXPECT_DEATH(read_from_ptr(arr2, arr2_size), ".*"); - - EXPECT_DEATH(write_to_ptr(arr32, u128()), ".*"); - EXPECT_DEATH(write_to_ptr(arr32_2, arr32_count, u32()), ".*"); - EXPECT_DEATH(write_to_ptr(arr32_2, arr32_count, u64()), ".*"); - EXPECT_DEATH(write_to_ptr(arr32_2, arr32_count, u128()), ".*"); - EXPECT_DEATH(read_from_ptr(arr32_2, arr32_count), ".*"); - EXPECT_DEATH(read_from_ptr(arr32_2, arr32_count), ".*"); - EXPECT_DEATH(read_from_ptr(arr32_2, arr32_count), ".*"); -#endif -#endif - delete[] arr; delete[] arr2; delete[] arr32; diff --git a/rpcs3/util/types.hpp b/rpcs3/util/types.hpp index c33724a054..6d081a96f9 100644 --- a/rpcs3/util/types.hpp +++ b/rpcs3/util/types.hpp @@ -1197,6 +1197,7 @@ namespace stx // Read object of type T from raw pointer, array, string, vector, or any contiguous container template + requires requires(U&& array) { std::size(array); std::data(array); } constexpr T read_from_ptr(U&& array, usz pos = 0, std::source_location src_loc = std::source_location::current()) { // TODO: ensure array element types are trivial @@ -1207,10 +1208,7 @@ constexpr T read_from_ptr(U&& array, usz pos = 0, std::source_location src_loc = if (!std::is_constant_evaluated()) { - if constexpr (requires { std::size(array); }) - { - ensure((pos + elements_per_value) <= std::size(array), src_loc); - } + ensure((pos + elements_per_value) <= std::size(array), src_loc); std::memcpy(+buf, &array[pos], sizeof(buf)); } @@ -1225,16 +1223,28 @@ constexpr T read_from_ptr(U&& array, usz pos = 0, std::source_location src_loc = return std::bit_cast(buf); } +// Read object of type T from raw pointer, array, string, vector, or any contiguous container template + requires (!requires(U&& array) { std::size(array); std::data(array); }) +constexpr T read_from_ptr_unsafe(U&& array, usz pos = 0) +{ + // TODO: ensure array element types are trivial + static_assert(sizeof(T) % sizeof(array[0]) == 0); + constexpr usz elements_per_value = sizeof(T) / sizeof(array[0]); + + std::decay_t buf[elements_per_value]; + std::memcpy(+buf, &array[pos], sizeof(buf)); + return std::bit_cast(buf); +} + +template + requires requires(U&& array) { std::size(array); std::data(array); } constexpr void write_to_ptr(U&& array, usz pos, const T& value, std::source_location src_loc = std::source_location::current()) { static_assert(sizeof(T) % sizeof(array[0]) == 0); constexpr usz elements_per_value = sizeof(T) / sizeof(array[0]); - if constexpr (requires { std::size(array); }) - { - ensure((pos + elements_per_value) <= std::size(array), src_loc); - } + ensure((pos + elements_per_value) <= std::size(array), src_loc); if (!std::is_constant_evaluated()) { @@ -1247,15 +1257,13 @@ constexpr void write_to_ptr(U&& array, usz pos, const T& value, std::source_loca } template + requires requires(U&& array) { std::size(array); std::data(array); } constexpr void write_to_ptr(U&& array, const T& value, std::source_location src_loc = std::source_location::current()) { static_assert(sizeof(T) % sizeof(array[0]) == 0); constexpr usz elements_per_value = sizeof(T) / sizeof(array[0]); - if constexpr (requires { std::size(array); }) - { - ensure(elements_per_value <= std::size(array), src_loc); - } + ensure(elements_per_value <= std::size(array), src_loc); if (!std::is_constant_evaluated()) { @@ -1267,6 +1275,24 @@ constexpr void write_to_ptr(U&& array, const T& value, std::source_location src_ } } +template + requires (!requires(U&& array) { std::size(array); std::data(array); }) +constexpr void write_to_ptr_unsafe(U&& array, usz pos, const T& value) +{ + static_assert(sizeof(T) % sizeof(array[0]) == 0); + + std::memcpy(static_cast(&array[pos]), &value, sizeof(value)); +} + +template + requires (!requires(U&& array) { std::size(array); std::data(array); }) +constexpr void write_to_ptr_unsafe(U&& array, const T& value) +{ + static_assert(sizeof(T) % sizeof(array[0]) == 0); + + std::memcpy(static_cast(&array[0]), &value, sizeof(value)); +} + constexpr struct aref_tag_t{} aref_tag{}; template @@ -1288,12 +1314,12 @@ public: constexpr T value() const { - return read_from_ptr(m_ptr); + return read_from_ptr_unsafe(m_ptr); } constexpr operator T() const { - return read_from_ptr(m_ptr); + return read_from_ptr_unsafe(m_ptr); } aref& operator=(const aref&) = delete;