PRX: Difference between revisions

From PS3 Developer wiki
Jump to navigation Jump to search
No edit summary
Line 17: Line 17:
*The second index can be extracted with 0x000000FF as a mask and is used as a base address for the target segment to patch and is added to r_offset.
*The second index can be extracted with 0x000000FF as a mask and is used as a base address for the target segment to patch and is added to r_offset.
*The first bit (0x80000000) is also set on earlier PRXs but it is currently unknown what it is used for.
*The first bit (0x80000000) is also set on earlier PRXs but it is currently unknown what it is used for.
=== PT_SCE_PPURELA Segment ===
It seems to be just a big table with following entries:
<source lang="C">
struct {
    u64 offset; // Offset in the second LOAD segment
    u16 unk0;  // ???
    u8  index;  // Seems that: 0 -> First LOAD segment, 1 -> Second LOAD segment
    u8  type;  // ??? Not sure what happens when type != 1.
    u32 unk1;  // ???
    u64 ptr;    // Offset of the pointer (while patching add the base address where the segment was allocated).
};
</source>
My guess is that this segment is used to patch the addresses of the second LOAD segments like this (this may be wrong, but so far it has been proven to work for my emulator's dynamic loader):
<source lang="C">
for (auto& rel : ppurela_table) {
    if (rel.type == 1) {
        const u32 addr = prx->load_segments[1].addr + rel.offset;
        const u32 value = prx->load_segments[rel.index].addr + rel.ptr;
        write32(addr, value);
    }
}
</source>
Has anyone worked on this previously? / Can someone confirm this? -- [[User:AlexAltea|AlexAltea]]




{{File Formats}}
{{File Formats}}
<noinclude>[[Category:Main]]</noinclude>
<noinclude>[[Category:Main]]</noinclude>

Revision as of 02:32, 28 December 2019

Overview

Playstation Relocatable Executable (PRX)

PRX2

A PRX module is PRX2 format only if ehdr.e_type is ET_SCE_EXEC or ET_SCE_RELEXEC.

A Program Segment is PRX2 format only if p_type is PT_SCE_RELA or PT_SCE_COMMENT.

Relocations

PS3

Relocations can be found in either PT_SCE_PPURELA segments or SHT_SCE_PPURELA / SHT_RELA sections. RELA relocations are standard relocations while PPURELA relocations have 2 segment (program header) indexes stored in r_sym of r_info.

  • The first index can be extracted with 0x7FFFFF00 as a mask and is used as a base address for r_addend. This sum will be the value applied to the patch.
  • The second index can be extracted with 0x000000FF as a mask and is used as a base address for the target segment to patch and is added to r_offset.
  • The first bit (0x80000000) is also set on earlier PRXs but it is currently unknown what it is used for.

PT_SCE_PPURELA Segment

It seems to be just a big table with following entries:

struct {
    u64 offset; // Offset in the second LOAD segment
    u16 unk0;   // ???
    u8  index;  // Seems that: 0 -> First LOAD segment, 1 -> Second LOAD segment
    u8  type;   // ??? Not sure what happens when type != 1.
    u32 unk1;   // ???
    u64 ptr;    // Offset of the pointer (while patching add the base address where the segment was allocated).
};

My guess is that this segment is used to patch the addresses of the second LOAD segments like this (this may be wrong, but so far it has been proven to work for my emulator's dynamic loader):

for (auto& rel : ppurela_table) {
    if (rel.type == 1) {
        const u32 addr = prx->load_segments[1].addr + rel.offset;
        const u32 value = prx->load_segments[rel.index].addr + rel.ptr;
        write32(addr, value);
    }
}

Has anyone worked on this previously? / Can someone confirm this? -- AlexAltea