Skip to content

Commit 7db20e9

Browse files
Merge branch 'master' into windows-clang
2 parents 390bc9a + db8437b commit 7db20e9

32 files changed

+529
-115
lines changed

rpcs3/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ if(BUILD_RPCS3_TESTS)
193193
PRIVATE
194194
tests/test.cpp
195195
tests/test_fmt.cpp
196+
tests/test_pair.cpp
197+
tests/test_tuple.cpp
196198
tests/test_simple_array.cpp
197199
tests/test_address_range.cpp
198200
)

rpcs3/Crypto/key_vault.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ SELF_KEY::SELF_KEY(u64 ver_start, u64 ver_end, u16 rev, u32 type, const std::str
1111
version_end = ver_end;
1212
revision = rev;
1313
self_type = type;
14-
hex_to_bytes(erk, e.c_str(), 0);
15-
hex_to_bytes(riv, r.c_str(), 0);
16-
hex_to_bytes(pub, pb.c_str(), 0);
17-
hex_to_bytes(priv, pr.c_str(), 0);
14+
hex_to_bytes(erk, e, 0);
15+
hex_to_bytes(riv, r, 0);
16+
hex_to_bytes(pub, pb, 0);
17+
hex_to_bytes(priv, pr, 0);
1818
curve_type = ct;
1919
}
2020

rpcs3/Crypto/utils.cpp

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
#include "sha1.h"
88
#include "sha256.h"
99
#include "key_vault.h"
10+
#include <charconv>
11+
#include <cstdlib>
1012
#include <cstring>
11-
#include <stdio.h>
12-
#include <time.h>
13+
#include <cstdio>
14+
#include <ctime>
1315
#include "Utilities/StrUtil.h"
1416
#include "Utilities/File.h"
1517

@@ -21,50 +23,24 @@
2123
// Auxiliary functions (endian swap, xor).
2224

2325
// Hex string conversion auxiliary functions.
24-
u64 hex_to_u64(const char* hex_str)
26+
void hex_to_bytes(unsigned char* data, std::string_view hex_str, unsigned int str_length)
2527
{
26-
auto length = std::strlen(hex_str);
27-
u64 tmp = 0;
28-
u64 result = 0;
29-
char c;
30-
31-
while (length--)
32-
{
33-
c = *hex_str++;
34-
if((c >= '0') && (c <= '9'))
35-
tmp = c - '0';
36-
else if((c >= 'a') && (c <= 'f'))
37-
tmp = c - 'a' + 10;
38-
else if((c >= 'A') && (c <= 'F'))
39-
tmp = c - 'A' + 10;
40-
else
41-
tmp = 0;
42-
result |= (tmp << (length * 4));
43-
}
44-
45-
return result;
46-
}
47-
48-
void hex_to_bytes(unsigned char* data, const char* hex_str, unsigned int str_length)
49-
{
50-
const auto strn_length = (str_length > 0) ? str_length : std::strlen(hex_str);
51-
auto data_length = strn_length / 2;
52-
char tmp_buf[3] = {0, 0, 0};
28+
const auto strn_length = (str_length > 0) ? str_length : hex_str.size();
5329

5430
// Don't convert if the string length is odd.
5531
if ((strn_length % 2) == 0)
5632
{
57-
while (data_length--)
33+
for (size_t i = 0; i < strn_length; i += 2)
5834
{
59-
tmp_buf[0] = *hex_str++;
60-
tmp_buf[1] = *hex_str++;
61-
62-
*data++ = static_cast<u8>(hex_to_u64(tmp_buf) & 0xFF);
35+
const auto [ptr, err] = std::from_chars(hex_str.data() + i, hex_str.data() + i + 2, *data++, 16);
36+
if (err != std::errc())
37+
{
38+
fmt::throw_exception("Failed to read hex string: %s", std::make_error_code(err).message());
39+
}
6340
}
6441
}
6542
}
6643

67-
6844
// Crypto functions (AES128-CBC, AES128-ECB, SHA1-HMAC and AES-CMAC).
6945
void aescbc128_decrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, usz len)
7046
{

rpcs3/Crypto/utils.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
#include "util/types.hpp"
88

9-
#include <stdlib.h>
9+
#include <cstdlib>
10+
#include <string_view>
1011

1112
enum { CRYPTO_MAX_PATH = 4096 };
1213

@@ -15,8 +16,7 @@ char* extract_file_name(const char* file_path, char real_file_name[CRYPTO_MAX_PA
1516
std::string sha256_get_hash(const char* data, usz size, bool lower_case);
1617

1718
// Hex string conversion auxiliary functions.
18-
u64 hex_to_u64(const char* hex_str);
19-
void hex_to_bytes(unsigned char *data, const char *hex_str, unsigned int str_length);
19+
void hex_to_bytes(unsigned char* data, std::string_view hex_str, unsigned int str_length);
2020

2121
// Crypto functions (AES128-CBC, AES128-ECB, SHA1-HMAC and AES-CMAC).
2222
void aescbc128_decrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, usz len);

rpcs3/Emu/Cell/Modules/cellSpurs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1230,7 +1230,7 @@ s32 _spurs::initialize(ppu_thread& ppu, vm::ptr<CellSpurs> spurs, u32 revision,
12301230
if (flags & SAF_UNKNOWN_FLAG_9) spuTgAttr->type |= 0x0800;
12311231
if (flags & SAF_SYSTEM_WORKLOAD_ENABLED) spuTgAttr->type |= SYS_SPU_THREAD_GROUP_TYPE_COOPERATE_WITH_SYSTEM;
12321232

1233-
if (s32 rc = sys_spu_thread_group_create(ppu, spurs.ptr(&CellSpurs::spuTG), nSpus, spuPriority, spuTgAttr))
1233+
if (s32 rc = sys_spu_thread_group_create(ppu, spurs.ptr(&CellSpurs::spuTG), nSpus, spuPriority, vm::unsafe_ptr_cast<reduced_sys_spu_thread_group_attribute>(spuTgAttr)))
12341234
{
12351235
ppu_execute<&sys_spu_image_close>(ppu, spurs.ptr(&CellSpurs::spuImg));
12361236
return rollback(), rc;

rpcs3/Emu/Cell/SPUThread.cpp

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,33 @@ static FORCE_INLINE void mov_rdata_avx(__m256i* dst, const __m256i* src)
303303
}
304304
#endif
305305

306+
// Check if only a single 16-bytes block has changed
307+
// Returning its position, or -1 if that is not the situation
308+
static inline usz scan16_rdata(const decltype(spu_thread::rdata)& _lhs, const decltype(spu_thread::rdata)& _rhs)
309+
{
310+
const auto lhs = reinterpret_cast<const v128*>(_lhs);
311+
const auto rhs = reinterpret_cast<const v128*>(_rhs);
312+
313+
u32 mask = 0;
314+
315+
for (usz i = 0; i < 8; i += 4)
316+
{
317+
const u32 a = (lhs[i + 0] != rhs[i + 0]) ? 1 : 0;
318+
const u32 b = (lhs[i + 1] != rhs[i + 1]) ? 1 : 0;
319+
const u32 c = (lhs[i + 2] != rhs[i + 2]) ? 1 : 0;
320+
const u32 d = (lhs[i + 3] != rhs[i + 3]) ? 1 : 0;
321+
322+
mask |= ((a << 0) + (b << 1) + (c << 2) + (d << 3)) << i;
323+
}
324+
325+
if (mask && (mask & (mask - 1)) == 0)
326+
{
327+
return std::countr_zero(mask);
328+
}
329+
330+
return umax;
331+
}
332+
306333
#ifdef _MSC_VER
307334
__forceinline
308335
#endif
@@ -3854,6 +3881,11 @@ bool spu_thread::do_putllc(const spu_mfc_cmd& args)
38543881
return false;
38553882
}
38563883

3884+
static const auto cast_as = [](void* ptr, usz pos){ return reinterpret_cast<u128*>(ptr) + pos; };
3885+
static const auto cast_as_const = [](const void* ptr, usz pos){ return reinterpret_cast<const u128*>(ptr) + pos; };
3886+
3887+
const usz diff16_pos = scan16_rdata(to_write, rdata);
3888+
38573889
auto [_oldd, _ok] = res.fetch_op([&](u64& r)
38583890
{
38593891
if ((r & -128) != rtime || (r & 127))
@@ -3975,8 +4007,19 @@ bool spu_thread::do_putllc(const spu_mfc_cmd& args)
39754007

39764008
if (cmp_rdata(rdata, super_data))
39774009
{
3978-
mov_rdata(super_data, to_write);
3979-
return true;
4010+
if (diff16_pos != umax)
4011+
{
4012+
// Do it with CMPXCHG16B if possible, this allows to improve accuracy whenever "RSX Accurate Reservations" is off
4013+
if (atomic_storage<u128>::compare_exchange(*cast_as(super_data, diff16_pos), *cast_as(rdata, diff16_pos), *cast_as_const(to_write, diff16_pos)))
4014+
{
4015+
return true;
4016+
}
4017+
}
4018+
else
4019+
{
4020+
mov_rdata(super_data, to_write);
4021+
return true;
4022+
}
39804023
}
39814024

39824025
return false;

rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -468,11 +468,11 @@ error_code sys_ppu_thread_restart(ppu_thread& ppu)
468468
return CELL_OK;
469469
}
470470

471-
error_code _sys_ppu_thread_create(ppu_thread& ppu, vm::ptr<u64> thread_id, vm::ptr<ppu_thread_param_t> param, u64 arg, u64 unk, s32 prio, u32 _stacksz, u64 flags, vm::cptr<char> threadname)
471+
error_code _sys_ppu_thread_create(ppu_thread& ppu, vm::ptr<u64> thread_id, vm::ptr<ppu_thread_param_t> param, u64 arg, u64 unk, s32 prio, u64 _stacksz, u64 flags, vm::cptr<char> threadname)
472472
{
473473
ppu.state += cpu_flag::wait;
474474

475-
sys_ppu_thread.warning("_sys_ppu_thread_create(thread_id=*0x%x, param=*0x%x, arg=0x%llx, unk=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)",
475+
sys_ppu_thread.warning("_sys_ppu_thread_create(thread_id=*0x%x, param=*0x%x, arg=0x%llx, unk=0x%llx, prio=%d, stacksize=0x%llx, flags=0x%llx, threadname=*0x%x)",
476476
thread_id, param, arg, unk, prio, _stacksz, flags, threadname);
477477

478478
// thread_id is checked for null in stub -> CELL_ENOMEM
@@ -497,7 +497,8 @@ error_code _sys_ppu_thread_create(ppu_thread& ppu, vm::ptr<u64> thread_id, vm::p
497497
const u32 tls = param->tls;
498498

499499
// Compute actual stack size and allocate
500-
const u32 stack_size = utils::align<u32>(std::max<u32>(_stacksz, 4096), 4096);
500+
// 0 and UINT64_MAX both convert to 4096
501+
const u64 stack_size = FN(x ? x : 4096)(utils::align<u64>(_stacksz, 4096));
501502

502503
auto& dct = g_fxo->get<lv2_memory_container>();
503504

@@ -507,7 +508,7 @@ error_code _sys_ppu_thread_create(ppu_thread& ppu, vm::ptr<u64> thread_id, vm::p
507508
return {CELL_ENOMEM, dct.size - dct.used};
508509
}
509510

510-
const vm::addr_t stack_base{vm::alloc(stack_size, vm::stack, 4096)};
511+
const vm::addr_t stack_base{vm::alloc(static_cast<u32>(stack_size), vm::stack, 4096)};
511512

512513
if (!stack_base)
513514
{
@@ -532,7 +533,7 @@ error_code _sys_ppu_thread_create(ppu_thread& ppu, vm::ptr<u64> thread_id, vm::p
532533
{
533534
ppu_thread_params p;
534535
p.stack_addr = stack_base;
535-
p.stack_size = stack_size;
536+
p.stack_size = static_cast<u32>(stack_size);
536537
p.tls_addr = tls;
537538
p.entry = entry;
538539
p.arg0 = arg;

rpcs3/Emu/Cell/lv2/sys_ppu_thread.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ error_code sys_ppu_thread_get_priority(ppu_thread& ppu, u32 thread_id, vm::ptr<s
5353
error_code sys_ppu_thread_get_stack_information(ppu_thread& ppu, vm::ptr<sys_ppu_thread_stack_t> sp);
5454
error_code sys_ppu_thread_stop(ppu_thread& ppu, u32 thread_id);
5555
error_code sys_ppu_thread_restart(ppu_thread& ppu);
56-
error_code _sys_ppu_thread_create(ppu_thread& ppu, vm::ptr<u64> thread_id, vm::ptr<ppu_thread_param_t> param, u64 arg, u64 arg4, s32 prio, u32 stacksize, u64 flags, vm::cptr<char> threadname);
56+
error_code _sys_ppu_thread_create(ppu_thread& ppu, vm::ptr<u64> thread_id, vm::ptr<ppu_thread_param_t> param, u64 arg, u64 arg4, s32 prio, u64 stacksize, u64 flags, vm::cptr<char> threadname);
5757
error_code sys_ppu_thread_start(ppu_thread& ppu, u32 thread_id);
5858
error_code sys_ppu_thread_rename(ppu_thread& ppu, u32 thread_id, vm::cptr<char> name);
5959
error_code sys_ppu_thread_recover_page_fault(ppu_thread& ppu, u32 thread_id);

rpcs3/Emu/Cell/lv2/sys_spu.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,12 @@ error_code sys_spu_thread_initialize(ppu_thread& ppu, vm::ptr<u32> thread, u32 g
767767
}
768768

769769
// Read thread name
770-
const std::string thread_name(attr_data.name.get_ptr(), std::max<u32>(attr_data.name_len, 1) - 1);
770+
std::string thread_name;
771+
772+
if (attr_data.name_len && !vm::read_string(attr_data.name.addr(), attr_data.name_len - 1, thread_name, true))
773+
{
774+
return { CELL_EFAULT, attr_data.name.addr() };
775+
}
771776

772777
const auto group = idm::get_unlocked<lv2_spu_group>(group_id);
773778

@@ -906,21 +911,40 @@ error_code sys_spu_thread_get_exit_status(ppu_thread& ppu, u32 id, vm::ptr<s32>
906911
return CELL_ESTAT;
907912
}
908913

909-
error_code sys_spu_thread_group_create(ppu_thread& ppu, vm::ptr<u32> id, u32 num, s32 prio, vm::ptr<sys_spu_thread_group_attribute> attr)
914+
error_code sys_spu_thread_group_create(ppu_thread& ppu, vm::ptr<u32> id, u32 num, s32 prio, vm::ptr<reduced_sys_spu_thread_group_attribute> attr)
910915
{
911916
ppu.state += cpu_flag::wait;
912917

913918
sys_spu.warning("sys_spu_thread_group_create(id=*0x%x, num=%d, prio=%d, attr=*0x%x)", id, num, prio, attr);
914919

915920
const s32 min_prio = g_ps3_process_info.has_root_perm() ? 0 : 16;
916921

917-
const sys_spu_thread_group_attribute attr_data = *attr;
922+
sys_spu_thread_group_attribute attr_data{};
923+
{
924+
const reduced_sys_spu_thread_group_attribute attr_reduced = *attr;
925+
attr_data.name = attr_reduced.name;
926+
attr_data.nsize = attr_reduced.nsize;
927+
attr_data.type = attr_reduced.type;
928+
929+
// Read container-id member at offset 12 bytes conditionally (that's what LV2 does)
930+
if (attr_data.type & SYS_SPU_THREAD_GROUP_TYPE_MEMORY_FROM_CONTAINER)
931+
{
932+
attr_data.ct = vm::unsafe_ptr_cast<sys_spu_thread_group_attribute>(attr)->ct;
933+
}
934+
}
918935

919936
if (attr_data.nsize > 0x80 || !num)
920937
{
921938
return CELL_EINVAL;
922939
}
923940

941+
std::string group_name;
942+
943+
if (attr_data.nsize && !vm::read_string(attr_data.name.addr(), attr_data.nsize - 1, group_name, true))
944+
{
945+
return { CELL_EFAULT, attr_data.name.addr() };
946+
}
947+
924948
const s32 type = attr_data.type;
925949

926950
bool use_scheduler = true;
@@ -1075,7 +1099,7 @@ error_code sys_spu_thread_group_create(ppu_thread& ppu, vm::ptr<u32> id, u32 num
10751099
return CELL_EBUSY;
10761100
}
10771101

1078-
const auto group = idm::make_ptr<lv2_spu_group>(std::string(attr_data.name.get_ptr(), std::max<u32>(attr_data.nsize, 1) - 1), num, prio, type, ct, use_scheduler, mem_size);
1102+
const auto group = idm::make_ptr<lv2_spu_group>(std::move(group_name), num, prio, type, ct, use_scheduler, mem_size);
10791103

10801104
if (!group)
10811105
{

rpcs3/Emu/Cell/lv2/sys_spu.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,18 @@ enum spu_stop_syscall : u32
8282
SYS_SPU_THREAD_STOP_SWITCH_SYSTEM_MODULE = 0x0120,
8383
};
8484

85-
struct sys_spu_thread_group_attribute
85+
struct reduced_sys_spu_thread_group_attribute
8686
{
8787
be_t<u32> nsize; // name length including NULL terminator
8888
vm::bcptr<char> name;
8989
be_t<s32> type;
90+
};
91+
92+
struct sys_spu_thread_group_attribute
93+
{
94+
be_t<u32> nsize;
95+
vm::bcptr<char> name;
96+
be_t<s32> type;
9097
be_t<u32> ct; // memory container id
9198
};
9299

@@ -360,7 +367,7 @@ error_code _sys_spu_image_close(ppu_thread&, vm::ptr<sys_spu_image> img);
360367
error_code _sys_spu_image_get_segments(ppu_thread&, vm::ptr<sys_spu_image> img, vm::ptr<sys_spu_segment> segments, s32 nseg);
361368
error_code sys_spu_thread_initialize(ppu_thread&, vm::ptr<u32> thread, u32 group, u32 spu_num, vm::ptr<sys_spu_image>, vm::ptr<sys_spu_thread_attribute>, vm::ptr<sys_spu_thread_argument>);
362369
error_code sys_spu_thread_set_argument(ppu_thread&, u32 id, vm::ptr<sys_spu_thread_argument> arg);
363-
error_code sys_spu_thread_group_create(ppu_thread&, vm::ptr<u32> id, u32 num, s32 prio, vm::ptr<sys_spu_thread_group_attribute> attr);
370+
error_code sys_spu_thread_group_create(ppu_thread&, vm::ptr<u32> id, u32 num, s32 prio, vm::ptr<reduced_sys_spu_thread_group_attribute> attr);
364371
error_code sys_spu_thread_group_destroy(ppu_thread&, u32 id);
365372
error_code sys_spu_thread_group_start(ppu_thread&, u32 id);
366373
error_code sys_spu_thread_group_suspend(ppu_thread&, u32 id);

0 commit comments

Comments
 (0)