mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-28 05:18:00 +03:00
Implement sys_spu_image_open_by_fd
Some checks are pending
Generate Translation Template / Generate Translation Template (push) Waiting to run
Build RPCS3 / RPCS3 Linux ubuntu-24.04 gcc (push) Waiting to run
Build RPCS3 / RPCS3 Linux ubuntu-24.04-arm clang (push) Waiting to run
Build RPCS3 / RPCS3 Linux ubuntu-24.04 clang (push) Waiting to run
Build RPCS3 / RPCS3 Windows (push) Waiting to run
Some checks are pending
Generate Translation Template / Generate Translation Template (push) Waiting to run
Build RPCS3 / RPCS3 Linux ubuntu-24.04 gcc (push) Waiting to run
Build RPCS3 / RPCS3 Linux ubuntu-24.04-arm clang (push) Waiting to run
Build RPCS3 / RPCS3 Linux ubuntu-24.04 clang (push) Waiting to run
Build RPCS3 / RPCS3 Windows (push) Waiting to run
This commit is contained in:
parent
ab7a1a6ec4
commit
7de2869a53
4 changed files with 72 additions and 25 deletions
|
@ -1343,10 +1343,13 @@ static fs::file CheckDebugSelf(const fs::file& s)
|
||||||
fs::file e = fs::make_stream<std::vector<u8>>();
|
fs::file e = fs::make_stream<std::vector<u8>>();
|
||||||
|
|
||||||
// Copy the data.
|
// Copy the data.
|
||||||
char buf[2048];
|
std::vector<u8> buf(std::min<usz>(s.size(), 4096));
|
||||||
while (const u64 size = s.read(buf, 2048))
|
|
||||||
|
usz read_pos = 0;
|
||||||
|
while (const u64 size = s.read_at(read_pos, buf.data(), buf.size()))
|
||||||
{
|
{
|
||||||
e.write(buf, size);
|
e.write(buf.data(), size);
|
||||||
|
read_pos += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
|
@ -1412,6 +1415,23 @@ fs::file decrypt_self(const fs::file& elf_or_self, const u8* klic_key, SelfAddit
|
||||||
// Make a new ELF file from this SELF.
|
// Make a new ELF file from this SELF.
|
||||||
return self_dec.MakeElf(isElf32);
|
return self_dec.MakeElf(isElf32);
|
||||||
}
|
}
|
||||||
|
else if (Emu.GetBoot().ends_with(".elf") || Emu.GetBoot().ends_with(".ELF"))
|
||||||
|
{
|
||||||
|
// Write the file back if the main executable is not signed
|
||||||
|
fs::file e = fs::make_stream<std::vector<u8>>();
|
||||||
|
|
||||||
|
// Copy the data.
|
||||||
|
std::vector<u8> buf(std::min<usz>(elf_or_self.size(), 4096));
|
||||||
|
|
||||||
|
usz read_pos = 0;
|
||||||
|
while (const u64 size = elf_or_self.read_at(read_pos, buf.data(), buf.size()))
|
||||||
|
{
|
||||||
|
e.write(buf.data(), size);
|
||||||
|
read_pos += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,7 +373,7 @@ const std::array<std::pair<ppu_intrp_func_t, std::string_view>, 1024> g_ppu_sysc
|
||||||
|
|
||||||
uns_func, uns_func, uns_func, uns_func, uns_func, //255-259 UNS
|
uns_func, uns_func, uns_func, uns_func, uns_func, //255-259 UNS
|
||||||
|
|
||||||
NULL_FUNC(sys_spu_image_open_by_fd), //260 (0x104)
|
BIND_SYSC(sys_spu_image_open_by_fd), //260 (0x104)
|
||||||
|
|
||||||
uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, //261-269 UNS
|
uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, //261-269 UNS
|
||||||
uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, //270-279 UNS
|
uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, uns_func, //270-279 UNS
|
||||||
|
|
|
@ -66,13 +66,14 @@ void fmt_class_string<spu_stop_syscall>::format(std::string& out, u64 arg)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_spu_image::load(const fs::file& stream)
|
bool sys_spu_image::load(const fs::file& stream)
|
||||||
{
|
{
|
||||||
const spu_exec_object obj{stream, 0, elf_opt::no_sections + elf_opt::no_data};
|
const spu_exec_object obj{stream, 0, elf_opt::no_sections + elf_opt::no_data};
|
||||||
|
|
||||||
if (obj != elf_error::ok)
|
if (obj != elf_error::ok)
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Failed to load SPU image: %s", obj.get_error());
|
sys_spu.error("Failed to load SPU image: %s", obj.get_error());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& shdr : obj.shdrs)
|
for (const auto& shdr : obj.shdrs)
|
||||||
|
@ -94,7 +95,7 @@ void sys_spu_image::load(const fs::file& stream)
|
||||||
const s32 nsegs = sys_spu_image::get_nsegs(obj.progs);
|
const s32 nsegs = sys_spu_image::get_nsegs(obj.progs);
|
||||||
|
|
||||||
const u32 mem_size = nsegs * sizeof(sys_spu_segment) + ::size32(stream);
|
const u32 mem_size = nsegs * sizeof(sys_spu_segment) + ::size32(stream);
|
||||||
const vm::ptr<sys_spu_segment> segs = vm::cast(vm::reserve_map(vm::user64km 0, 0x10000000)->alloc(mem_size));
|
const vm::ptr<sys_spu_segment> segs = vm::cast(vm::reserve_map(vm::user64k, 0, 0x10000000)->alloc(mem_size));
|
||||||
|
|
||||||
//const u32 entry = obj.header.e_entry;
|
//const u32 entry = obj.header.e_entry;
|
||||||
|
|
||||||
|
@ -116,6 +117,7 @@ void sys_spu_image::load(const fs::file& stream)
|
||||||
this->segs = vm::null;
|
this->segs = vm::null;
|
||||||
|
|
||||||
vm::page_protect(segs.addr(), utils::align(mem_size, 4096), 0, 0, vm::page_writable);
|
vm::page_protect(segs.addr(), utils::align(mem_size, 4096), 0, 0, vm::page_writable);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_spu_image::free() const
|
void sys_spu_image::free() const
|
||||||
|
@ -517,28 +519,52 @@ error_code sys_spu_image_open(ppu_thread& ppu, vm::ptr<sys_spu_image> img, vm::c
|
||||||
|
|
||||||
u128 klic = g_fxo->get<loaded_npdrm_keys>().last_key();
|
u128 klic = g_fxo->get<loaded_npdrm_keys>().last_key();
|
||||||
|
|
||||||
fs::file elf_file;
|
const fs::file elf_file = decrypt_self(file, reinterpret_cast<const u8*>(&klic));
|
||||||
|
|
||||||
// Check for SELF header
|
if (!elf_file || !img->load(elf_file))
|
||||||
u32 file_type = umax;
|
|
||||||
file.read_at(0, &file_type, sizeof(file_type));
|
|
||||||
|
|
||||||
if (file_type == "SCE\0"_u32)
|
|
||||||
{
|
|
||||||
elf_file = decrypt_self(file, reinterpret_cast<u8*>(&klic));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
elf_file = std::move(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!elf_file)
|
|
||||||
{
|
{
|
||||||
sys_spu.error("sys_spu_image_open(): file %s is illegal for SPU image!", path);
|
sys_spu.error("sys_spu_image_open(): file %s is illegal for SPU image!", path);
|
||||||
return {CELL_ENOEXEC, path};
|
return {CELL_ENOEXEC, path};
|
||||||
}
|
}
|
||||||
|
|
||||||
img->load(elf_file);
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_code sys_spu_image_open_by_fd(ppu_thread& ppu, vm::ptr<sys_spu_image> img, s32 fd, s64 offset)
|
||||||
|
{
|
||||||
|
ppu.state += cpu_flag::wait;
|
||||||
|
|
||||||
|
sys_spu.warning("sys_spu_image_open_by_fd(img=*0x%x, fd=%d, offset=0x%x)", img, fd, offset);
|
||||||
|
|
||||||
|
const auto file = idm::get_unlocked<lv2_fs_object, lv2_file>(fd);
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
return CELL_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
{
|
||||||
|
return CELL_ENOEXEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard lock(file->mp->mutex);
|
||||||
|
|
||||||
|
if (!file->file)
|
||||||
|
{
|
||||||
|
return CELL_EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
u128 klic = g_fxo->get<loaded_npdrm_keys>().last_key();
|
||||||
|
|
||||||
|
const fs::file elf_file = decrypt_self(lv2_file::make_view(file, offset), reinterpret_cast<const u8*>(&klic));
|
||||||
|
|
||||||
|
if (!img->load(elf_file))
|
||||||
|
{
|
||||||
|
sys_spu.error("sys_spu_image_open(): file %s is illegal for SPU image!", file->name.data());
|
||||||
|
return {CELL_ENOEXEC, file->name.data()};
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,7 +596,7 @@ error_code _sys_spu_image_close(ppu_thread& ppu, vm::ptr<sys_spu_image> img)
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure(vm::dealloc(handle->segs.addr(), vm::main));
|
ensure(vm::dealloc(handle->segs.addr(), vm::user64k));
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -225,7 +225,7 @@ struct sys_spu_image
|
||||||
return num_segs;
|
return num_segs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(const fs::file& stream);
|
bool load(const fs::file& stream);
|
||||||
void free() const;
|
void free() const;
|
||||||
static void deploy(u8* loc, std::span<const sys_spu_segment> segs, bool is_verbose = true);
|
static void deploy(u8* loc, std::span<const sys_spu_segment> segs, bool is_verbose = true);
|
||||||
};
|
};
|
||||||
|
@ -354,6 +354,7 @@ class ppu_thread;
|
||||||
error_code sys_spu_initialize(ppu_thread&, u32 max_usable_spu, u32 max_raw_spu);
|
error_code sys_spu_initialize(ppu_thread&, u32 max_usable_spu, u32 max_raw_spu);
|
||||||
error_code _sys_spu_image_get_information(ppu_thread&, vm::ptr<sys_spu_image> img, vm::ptr<u32> entry_point, vm::ptr<s32> nsegs);
|
error_code _sys_spu_image_get_information(ppu_thread&, vm::ptr<sys_spu_image> img, vm::ptr<u32> entry_point, vm::ptr<s32> nsegs);
|
||||||
error_code sys_spu_image_open(ppu_thread&, vm::ptr<sys_spu_image> img, vm::cptr<char> path);
|
error_code sys_spu_image_open(ppu_thread&, vm::ptr<sys_spu_image> img, vm::cptr<char> path);
|
||||||
|
error_code sys_spu_image_open_by_fd(ppu_thread&, vm::ptr<sys_spu_image> img, s32 fd, s64 offset);
|
||||||
error_code _sys_spu_image_import(ppu_thread&, vm::ptr<sys_spu_image> img, u32 src, u32 size, u32 arg4);
|
error_code _sys_spu_image_import(ppu_thread&, vm::ptr<sys_spu_image> img, u32 src, u32 size, u32 arg4);
|
||||||
error_code _sys_spu_image_close(ppu_thread&, vm::ptr<sys_spu_image> img);
|
error_code _sys_spu_image_close(ppu_thread&, vm::ptr<sys_spu_image> img);
|
||||||
error_code _sys_spu_image_get_segments(ppu_thread&, vm::ptr<sys_spu_image> img, vm::ptr<sys_spu_segment> segments, s32 nseg);
|
error_code _sys_spu_image_get_segments(ppu_thread&, vm::ptr<sys_spu_image> img, vm::ptr<sys_spu_segment> segments, s32 nseg);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue