From 649d68a00f11e96bd2e3445868728bb3342c134d Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 31 Aug 2017 20:38:17 +0300 Subject: [PATCH] +sys_spu_elf_get_segments --- rpcs3/Emu/Cell/Modules/sys_spu_.cpp | 40 +++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/sys_spu_.cpp b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp index 1c9dbbc088..cbe86575ee 100644 --- a/rpcs3/Emu/Cell/Modules/sys_spu_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp @@ -229,9 +229,45 @@ error_code sys_spu_elf_get_information(u32 elf_img, vm::ptr entry, vm::ptr< return CELL_OK; } -s32 sys_spu_elf_get_segments(u32 elf_img, vm::ptr segments, s32 nseg) +error_code sys_spu_elf_get_segments(u32 elf_img, vm::ptr segments, s32 nseg) { - sysPrxForUser.todo("sys_spu_elf_get_segments(elf_img=0x%x, segments=*0x%x, nseg=0x%x)", elf_img, segments, nseg); + sysPrxForUser.warning("sys_spu_elf_get_segments(elf_img=0x%x, segments=*0x%x, nseg=0x%x)", elf_img, segments, nseg); + + // Initialize ELF loader + vm::var info(spu_elf_info{}); + + if (auto res = info->init(vm::cast(elf_img))) + { + return res; + } + + // Load ELF header + vm::var> ehdr(elf_ehdr{}); + + if (info->ldr->get_ehdr(ehdr) || ehdr->e_machine != elf_machine::spu || !ehdr->e_phnum) + { + return CELL_ENOEXEC; + } + + // Load program headers + vm::var[]> phdr(ehdr->e_phnum); + + if (info->ldr->get_phdr(phdr, ehdr->e_phnum)) + { + return CELL_ENOEXEC; + } + + const s32 num_segs = sys_spu_image::fill(segments, nseg, phdr, elf_img); + + if (num_segs == -2) + { + return CELL_ENOMEM; + } + else if (num_segs < 0) + { + return CELL_ENOEXEC; + } + return CELL_OK; }