PRX

From PS3 Developer wiki
Revision as of 22:05, 19 January 2020 by CelesteBlue (talk | contribs) (→‎Imports)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Overview

Playstation Relocatable Executable (PRX)

PRX2

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 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

#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

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

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

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.