mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
Implement sys_spu_image_open_by_fd
This commit is contained in:
parent
c2bfcb0bde
commit
fe348344b3
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>>();
|
||||
|
||||
// Copy the data.
|
||||
char buf[2048];
|
||||
while (const u64 size = s.read(buf, 2048))
|
||||
std::vector<u8> buf(std::min<usz>(s.size(), 4096));
|
||||
|
||||
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;
|
||||
|
@ -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.
|
||||
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 {};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
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, 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};
|
||||
|
||||
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)
|
||||
|
@ -94,7 +95,7 @@ void sys_spu_image::load(const fs::file& stream)
|
|||
const s32 nsegs = sys_spu_image::get_nsegs(obj.progs);
|
||||
|
||||
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;
|
||||
|
||||
|
@ -116,6 +117,7 @@ void sys_spu_image::load(const fs::file& stream)
|
|||
this->segs = vm::null;
|
||||
|
||||
vm::page_protect(segs.addr(), utils::align(mem_size, 4096), 0, 0, vm::page_writable);
|
||||
return true;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
fs::file elf_file;
|
||||
const fs::file elf_file = decrypt_self(file, reinterpret_cast<const u8*>(&klic));
|
||||
|
||||
// Check for SELF header
|
||||
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)
|
||||
if (!elf_file || !img->load(elf_file))
|
||||
{
|
||||
sys_spu.error("sys_spu_image_open(): file %s is illegal for SPU image!", 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;
|
||||
}
|
||||
|
||||
|
@ -570,7 +596,7 @@ error_code _sys_spu_image_close(ppu_thread& ppu, vm::ptr<sys_spu_image> img)
|
|||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
ensure(vm::dealloc(handle->segs.addr(), vm::main));
|
||||
ensure(vm::dealloc(handle->segs.addr(), vm::user64k));
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ struct sys_spu_image
|
|||
return num_segs;
|
||||
}
|
||||
|
||||
void load(const fs::file& stream);
|
||||
bool load(const fs::file& stream);
|
||||
void free() const;
|
||||
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_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_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_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);
|
||||
|
|
Loading…
Add table
Reference in a new issue