PRX: Difference between revisions

From PS3 Developer wiki
Jump to navigation Jump to search
(more info, second load segment is nothing special (maps to .data, .opd, .toc, etc). nothing new.)
No edit summary
Line 1: Line 1:
=Overview=
= Overview =
 
'''S'''igned '''P'''PU '''R'''elocatable E'''x'''ecutable (SPRX)
'''S'''igned '''P'''PU '''R'''elocatable E'''x'''ecutable (SPRX)


=Structure=
= Structure =
 
First LOAD segment p_paddr points to module info.
First LOAD segment p_paddr points to module info.
==Module Info==
 
== Module Info ==
 
{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
Line 43: Line 47:
|}
|}


===Exports===
=== Exports ===
 
{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
Line 98: Line 103:
|}
|}


===Imports===
=== Imports ===
 
{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
Line 166: Line 172:


== Relocations ==
== Relocations ==
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.  
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 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.  
Line 171: Line 178:
*The first bit (0x80000000) is also set on earlier PRX's but it is currently unknown what it is used for.
*The first bit (0x80000000) is also set on earlier PRX's but it is currently unknown what it is used for.


= FNID generation =
== symbol name suffix ==
symbol_name_suffix: 6759659904250490566427499489741A
To calculate FNID value of exported/imported symbol from .PRX you need to take SHA-1 hash over concatenation of symbol's name and symbol_name_suffix and then grab first 4 bytes from it and reverse these bytes (because of little-endian).
Let's take, for example, ''_sys_sprintf'':
  ''SHA1''('_sys_sprintf' + '\x67\x59\x65\x99\x04\x25\x04\x90\x56\x64\x27\x49\x94\x89\x74\x1A') = '''FEEAF9A1'''23D7D1A7619B40CD52500F9735A852A4
  ''FNID''('_sys_sprintf') = ''swap_uint32''('''0xFEEAF9A1''') = '''0xA1F9EAFE'''.
For C++ functions you should use mangled representation of symbol's name.
For example, mangled name of ''std::runtime_error::what() const'' is ''_ZNKSt13runtime_error4whatEv'' and FNID('_ZNKSt13runtime_error4whatEv') = '''0x5333BDC9'''.
More complex example:
FNID(mangle('std::basic_filebuf<wchar_t, std::char_traits<wchar_t> >::seekpos(std::fpos<std::
_Mbstatet>, std::_Iosb<int>::_Openmode)')) = FNID('_ZNSt13basic_filebufIwSt11char_traitsIwEE7seekposESt4fposISt9_MbstatetENSt5_IosbIiE9_OpenmodeE') = '''0xB6A4D760'''
noname_nid_suffix: 0xbc5eba9e042504905b64274994d9c41f
For import stub's with no names, you must use SHA1 over concatenation of symbol's name and noname_nid_suffix as an ascii string. Some examples of noname imports are module_start, module_info, and module_stop.
  ''SHA1''('module_info' + '0xbc5eba9e042504905b64274994d9c41f') = '''1630f4d7'''0bf3df419db9d481983411fd3130482a = '''0xD7F43016'''


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

Revision as of 19:34, 23 December 2019

Overview

Signed PPU Relocatable Executable (SPRX)

Structure

First LOAD segment p_paddr points to module info.

Module Info

Offset Type Description
+0 short Module attributes
+2 char[2] Module version
+4 char[28] Module name
+32 long TOC address
+36 long Pointer to the start of exports section
+40 long Pointer to end of exports section
+44 long Points to the start of imports section
+48 long Points to the end of imports section

Exports

Offset Type Description
+0 char[2] Structure size (0x1C 32-bit or 0x28 64-bit), padding
+2 short Version
+4 short Attributes
+6 short Number of functions
+8 short Number of variables
+10 short Number of thread local storage variables
+12 char Hash info
+13 char Thread local storage hash info
+14 char[2] Reserved
+16 long Pointer to exported library name
+20 long Pointer to function NID table
+24 long Pointer to function stub table

Imports

Offset Type Description
+0 char Structure size (0x2C)
+1 char Unused
+2 short Version
+4 short Attributes. AUTO_EXPORT=0x0001, WEAK_EXPORT=0x0002, NOLINK_EXPORT=0x0004, WEAK_IMPORT=0x0008, 0x2000 seems to indicate a non-PRX library (like "stdc" or "allocator") that comes from somewhere else (LV2?)
+6 short Number of functions
+8 short Number of variables
+10 short Number of thread local storage variables
+12 byte[4] reserved
+16 long Pointer to imported library name.
+20 long Pointer to the list of NID's for the exported functions.
+24 long Pointer to the list of exported functions.
+28 long var_nid_table
+32 long var_entry_table
+36 long tls_nid_table
+40 long tls_entry_table

Relocations

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 PRX's but it is currently unknown what it is used for.