PRX: Difference between revisions
CelesteBlue (talk | contribs) (→PT_SCE_PPURELA Segment: Remve outdated info) |
CelesteBlue (talk | contribs) |
||
(6 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
= PRX2 = | = PRX2 = | ||
PRX2 is only present on PSVita. | PRX2 is only present on PSVita. PSP and PS3 use PRX version 1. | ||
== Recognition == | |||
A PRX module is PRX2 format only if ehdr.e_type is ET_SCE_EXEC or ET_SCE_RELEXEC. | 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. | A Program Segment is PRX2 format only if p_type is PT_SCE_RELA or PT_SCE_COMMENT. | ||
= Module Info = | |||
PS3 and PSP PRX embed Module Info version 0. | |||
== Location == | |||
For PS3 (?and PSP?), it is located in text segment (first LOAD segment) at offset Elf32_Phdrs[text_seg_id].p_paddr - Elf32_Phdrs[text_seg_id].p_offset. Or more simply: at offset Elf32_Phdrs[text_seg_id].p_paddr in the ELF file. | |||
== Structure == | |||
<source lang="C"> | |||
#define MODULE_NAME_MAX_LEN 27 | |||
typedef struct sceModuleInfo_common { // size is 0x20 | |||
unsigned short modattr; | |||
unsigned char modver[2]; | |||
char modname[MODULE_NAME_MAX_LEN]; | |||
unsigned char infover; | |||
} sceModuleInfo_common; | |||
typedef struct sceModuleInfo_v0 { // size is 0x34 | |||
sceModuleInfo_common c; | |||
Elf32_Addr gp_value; | |||
Elf32_Addr libent_top; | |||
Elf32_Addr libent_btm; | |||
Elf32_Addr libstub_top; | |||
Elf32_Addr libstub_btm; | |||
} sceModuleInfo_v0; | |||
</source> | |||
= Exports = | |||
PS3 uses exports structure of size 0x1C ?or 0x28 in 64bits?. | |||
<source lang="C"> | |||
typedef struct _scelibent_common { // size is 0x10 | |||
unsigned char size; | |||
unsigned char auxattribute; | |||
unsigned short version; | |||
unsigned short attribute; | |||
unsigned short nfunc; | |||
unsigned short nvar; | |||
unsigned short ntls; | |||
unsigned char hashinfo; | |||
unsigned char hashinfotls; | |||
unsigned char reserved; | |||
unsigned char nidaltsets; | |||
} sceKernelLibraryEntryTable_common; | |||
typedef struct _scelibent_1C { // size is 0x1C | |||
sceKernelLibraryEntryTable_common c; | |||
Elf32_Addr libname; | |||
Elf32_Addr nid_table; | |||
Elf32_Addr entry_table; | |||
} sceKernelLibraryEntryTable_1C; | |||
</source> | |||
= Imports = | |||
PS3 use imports structures of size 0x2C. | |||
<source lang="C"> | |||
typedef struct _scelibstub_common { // size is 0xC | |||
unsigned short size; | |||
unsigned short version; | |||
unsigned short attribute; | |||
unsigned short nfunc; | |||
unsigned short nvar; | |||
unsigned short ntls; | |||
} sceKernelLibraryStubTable_common; | |||
typedef struct _scelibstub_2C { // size is 0x2C | |||
sceKernelLibraryStubTable_common c; | |||
unsigned char reserved[4]; | |||
Elf32_Addr libname; | |||
Elf32_Addr func_nid_table; | |||
Elf32_Addr func_entry_table; | |||
Elf32_Addr var_nid_table; | |||
Elf32_Addr var_entry_table; | |||
Elf32_Addr tls_nid_table; | |||
Elf32_Addr tls_entry_table; | |||
} sceKernelLibraryStubTable_2C; | |||
</source> | |||
= Relocations = | = Relocations = |
Latest revision as of 22:05, 19 January 2020
Overview[edit | edit source]
Playstation Relocatable Executable (PRX)
PRX2[edit | edit source]
PRX2 is only present on PSVita. PSP and PS3 use PRX version 1.
Recognition[edit | edit source]
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.
Module Info[edit | edit source]
PS3 and PSP PRX embed Module Info version 0.
Location[edit | edit source]
For PS3 (?and PSP?), it is located in text segment (first LOAD segment) at offset Elf32_Phdrs[text_seg_id].p_paddr - Elf32_Phdrs[text_seg_id].p_offset. Or more simply: at offset Elf32_Phdrs[text_seg_id].p_paddr in the ELF file.
Structure[edit | edit source]
#define MODULE_NAME_MAX_LEN 27
typedef struct sceModuleInfo_common { // size is 0x20
unsigned short modattr;
unsigned char modver[2];
char modname[MODULE_NAME_MAX_LEN];
unsigned char infover;
} sceModuleInfo_common;
typedef struct sceModuleInfo_v0 { // size is 0x34
sceModuleInfo_common c;
Elf32_Addr gp_value;
Elf32_Addr libent_top;
Elf32_Addr libent_btm;
Elf32_Addr libstub_top;
Elf32_Addr libstub_btm;
} sceModuleInfo_v0;
Exports[edit | edit source]
PS3 uses exports structure of size 0x1C ?or 0x28 in 64bits?.
typedef struct _scelibent_common { // size is 0x10
unsigned char size;
unsigned char auxattribute;
unsigned short version;
unsigned short attribute;
unsigned short nfunc;
unsigned short nvar;
unsigned short ntls;
unsigned char hashinfo;
unsigned char hashinfotls;
unsigned char reserved;
unsigned char nidaltsets;
} sceKernelLibraryEntryTable_common;
typedef struct _scelibent_1C { // size is 0x1C
sceKernelLibraryEntryTable_common c;
Elf32_Addr libname;
Elf32_Addr nid_table;
Elf32_Addr entry_table;
} sceKernelLibraryEntryTable_1C;
Imports[edit | edit source]
PS3 use imports structures of size 0x2C.
typedef struct _scelibstub_common { // size is 0xC
unsigned short size;
unsigned short version;
unsigned short attribute;
unsigned short nfunc;
unsigned short nvar;
unsigned short ntls;
} sceKernelLibraryStubTable_common;
typedef struct _scelibstub_2C { // size is 0x2C
sceKernelLibraryStubTable_common c;
unsigned char reserved[4];
Elf32_Addr libname;
Elf32_Addr func_nid_table;
Elf32_Addr func_entry_table;
Elf32_Addr var_nid_table;
Elf32_Addr var_entry_table;
Elf32_Addr tls_nid_table;
Elf32_Addr tls_entry_table;
} sceKernelLibraryStubTable_2C;
Relocations[edit | edit source]
PS3[edit | edit source]
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.
|