diff --git a/rpcs3/Emu/Cell/Modules/sys_spu_.cpp b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp index 091eeb6069..4ffe40371e 100644 --- a/rpcs3/Emu/Cell/Modules/sys_spu_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp @@ -99,7 +99,7 @@ struct spu_elf_info { u8 e_class; vm::bptr ldr; - + struct sce_hdr { be_t se_magic; @@ -170,7 +170,7 @@ struct spu_elf_info { return CELL_ENOEXEC; } - + e_class = ehdr->e_class; ldr = vm::get_addr(&_overlay); ldr->_vtable = vm::cast(u32{e_class}); // TODO @@ -212,6 +212,7 @@ error_code sys_spu_image_import(vm::ptr img, u32 src, u32 type) return res; } + // Reject SCE header if (info->sce0.se_magic == 0x53434500) { return CELL_ENOEXEC; @@ -249,7 +250,7 @@ error_code sys_spu_image_import(vm::ptr img, u32 src, u32 type) return _sys_spu_image_import(img, src, img_size, 0); } - else if (type == SYS_SPU_IMAGE_DIRECT) + else { s32 num_segs = sys_spu_image::get_nsegs(phdr); @@ -268,22 +269,16 @@ error_code sys_spu_image_import(vm::ptr img, u32 src, u32 type) return CELL_ENOMEM; } - if (sys_spu_image::fill(segs, phdr, src) != num_segs) + if (sys_spu_image::fill(segs, num_segs, phdr, src) != num_segs) { vm::dealloc(segs.addr()); return CELL_ENOEXEC; } - img->type = SYS_SPU_IMAGE_TYPE_USER; + img->type = SYS_SPU_IMAGE_TYPE_USER; img->segs = segs; return CELL_OK; } - else - { - return CELL_EINVAL; - } - - return CELL_OK; } error_code sys_spu_image_close(vm::ptr img) diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index b2c1b2e80a..b442ab7702 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -52,7 +52,7 @@ void sys_spu_image::load(const fs::file& stream) stream.seek(0); stream.read(vm::base(src), stream.size()); - if (nsegs < 0 || sys_spu_image::fill(segs, obj.progs, src) != nsegs) + if (nsegs < 0 || sys_spu_image::fill(segs, nsegs, obj.progs, src) != nsegs) { fmt::throw_exception("Failed to load SPU segments (%d)" HERE, nsegs); } diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.h b/rpcs3/Emu/Cell/lv2/sys_spu.h index da3692e7b2..5e06139953 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.h +++ b/rpcs3/Emu/Cell/lv2/sys_spu.h @@ -112,7 +112,7 @@ struct sys_spu_image vm::ps3::bptr segs; be_t nsegs; - template + template static s32 get_nsegs(const Phdrs& phdrs) { s32 num_segs = 0; @@ -128,7 +128,7 @@ struct sys_spu_image { num_segs += 2; } - else + else if (phdr.p_type == 1 || CountInfo) { num_segs += 1; } @@ -137,8 +137,8 @@ struct sys_spu_image return num_segs; } - template - static s32 fill(vm::ps3::ptr segs, const Phdrs& phdrs, u32 src) + template + static s32 fill(vm::ps3::ptr segs, s32 nsegs, const Phdrs& phdrs, u32 src) { s32 num_segs = 0; @@ -148,6 +148,11 @@ struct sys_spu_image { if (phdr.p_filesz) { + if (num_segs >= nsegs) + { + return -2; + } + auto* seg = &segs[num_segs++]; seg->type = SYS_SPU_SEGMENT_TYPE_COPY; seg->ls = static_cast(phdr.p_vaddr); @@ -157,6 +162,11 @@ struct sys_spu_image if (phdr.p_memsz > phdr.p_filesz) { + if (num_segs >= nsegs) + { + return -2; + } + auto* seg = &segs[num_segs++]; seg->type = SYS_SPU_SEGMENT_TYPE_FILL; seg->ls = static_cast(phdr.p_vaddr + phdr.p_filesz); @@ -164,14 +174,19 @@ struct sys_spu_image seg->addr = 0; } } - else if (phdr.p_type == 4) + else if (WriteInfo && phdr.p_type == 4) { + if (num_segs >= nsegs) + { + return -2; + } + auto* seg = &segs[num_segs++]; seg->type = SYS_SPU_SEGMENT_TYPE_INFO; seg->size = 0x20; seg->addr = static_cast(phdr.p_offset + 0x14 + src); } - else + else if (phdr.p_type != 4) { return -1; } @@ -283,7 +298,7 @@ error_code sys_spu_thread_group_destroy(u32 id); error_code sys_spu_thread_group_start(ppu_thread&, u32 id); error_code sys_spu_thread_group_suspend(u32 id); error_code sys_spu_thread_group_resume(u32 id); -error_code sys_spu_thread_group_yield(u32 id); +error_code sys_spu_thread_group_yield(u32 id); error_code sys_spu_thread_group_terminate(u32 id, s32 value); error_code sys_spu_thread_group_join(ppu_thread&, u32 id, vm::ps3::ptr cause, vm::ps3::ptr status); error_code sys_spu_thread_group_set_priority(u32 id, s32 priority);