diff --git a/rpcs3/Emu/Cell/PPUInterpreter.cpp b/rpcs3/Emu/Cell/PPUInterpreter.cpp index a3c6611b15..3fa6d09f7b 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/PPUInterpreter.cpp @@ -501,7 +501,7 @@ auto ppu_feed_data(ppu_thread& ppu, u64 addr) if (raddr / 128 == addr / 128) src = &ppu.rdata[addr & 127], size = std::min(128 - (addr % 128), sizeof(T)); else - src = &ppu.rdata[0], size = (addr + u32{sizeof(T)}) % 127, offs = sizeof(T) - size; + src = &ppu.rdata[0], size = (addr + u32{sizeof(T)}) % 128, offs = sizeof(T) - size; if (std::memcmp(buffer + offs, src, size)) { diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 81bb6fd89e..1d1f659be0 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -427,6 +427,12 @@ void spu_load_exec(const spu_exec_object& elf) { if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz) { + if (prog.p_vaddr >= SPU_LS_SIZE || prog.p_filesz > SPU_LS_SIZE - prog.p_vaddr) + { + spu_log.error("spu_load_exec: skipping segment with vaddr=0x%x filesz=0x%x (exceeds LS=0x%x)", prog.p_vaddr, prog.p_filesz, static_cast(SPU_LS_SIZE)); + continue; + } + std::memcpy(spu->_ptr(prog.p_vaddr), prog.bin.data(), prog.p_filesz); } } @@ -496,6 +502,12 @@ void spu_load_rel_exec(const spu_rel_object& elf) { if (shdr.sh_type == sec_type::sht_progbits && shdr.sh_flags().all_of(sh_flag::shf_alloc)) { + if (offs >= SPU_LS_SIZE || shdr.sh_size > SPU_LS_SIZE - offs) + { + spu_log.error("spu_load_rel_exec: skipping section at offs=0x%x sh_size=0x%x (exceeds LS=0x%x)", offs, shdr.sh_size, static_cast(SPU_LS_SIZE)); + break; + } + std::memcpy(spu->_ptr(offs), shdr.get_bin().data(), shdr.sh_size); offs = utils::align(offs + shdr.sh_size, 4); }