NSO: Difference between revisions
No edit summary |
No edit summary |
||
(19 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
NSO is the main executable format. | NSO is the main executable format. | ||
It starts with the "NSO" header and mainly describes .text, .rodata, and .data segments (like a short-form of ELF program headers) | It starts with the "NSO" header and mainly describes .text, .rodata, and .data segments (like a short-form of ELF program headers). If the segments are compressed, they are compressed using LZ4. | ||
= | = NsoHeader = | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 12: | Line 12: | ||
| 0x0 | | 0x0 | ||
| 4 | | 4 | ||
| | | Signature ("NSO0") | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
Line 36: | Line 20: | ||
| 0x8 | | 0x8 | ||
| 4 | | 4 | ||
| | | Reserved | ||
|- | |- | ||
| 0xC | | 0xC | ||
| 4 | | 4 | ||
| Flags | | [[#Flags|Flags]] | ||
|- | |- | ||
| 0x10 | | 0x10 | ||
| | | 0x4 | ||
| TextFileOffset | | TextFileOffset | ||
|- | |- | ||
| 0x14 | | 0x14 | ||
| | | 0x4 | ||
| TextMemoryOffset | | TextMemoryOffset | ||
|- | |- | ||
| 0x18 | | 0x18 | ||
| | | 0x4 | ||
| TextSize | | TextSize | ||
|- | |- | ||
| 0x1C | | 0x1C | ||
| | | 0x4 | ||
| ModuleNameOffset | | ModuleNameOffset (calculated by sizeof(header)) | ||
|- | |- | ||
| 0x20 | | 0x20 | ||
| | | 0x4 | ||
| RoFileOffset | | RoFileOffset | ||
|- | |- | ||
| 0x24 | | 0x24 | ||
| | | 0x4 | ||
| RoMemoryOffset | | RoMemoryOffset | ||
|- | |- | ||
| 0x28 | | 0x28 | ||
| | | 0x4 | ||
| RoSize | | RoSize | ||
|- | |- | ||
| 0x2C | | 0x2C | ||
| | | 0x4 | ||
| ModuleNameSize | | ModuleNameSize | ||
|- | |- | ||
| 0x30 | | 0x30 | ||
| | | 0x4 | ||
| DataFileOffset | | DataFileOffset | ||
|- | |- | ||
| 0x34 | | 0x34 | ||
| | | 0x4 | ||
| DataMemoryOffset | | DataMemoryOffset | ||
|- | |- | ||
| 0x38 | | 0x38 | ||
| | | 0x4 | ||
| DataSize | | DataSize | ||
|- | |- | ||
| 0x3C | | 0x3C | ||
| | | 0x4 | ||
| BssSize | | BssSize | ||
|- | |- | ||
| 0x40 | | 0x40 | ||
| 0x20 | | 0x20 | ||
| | | [[#ModuleId|ModuleId]] | ||
|- | |- | ||
| 0x60 | | 0x60 | ||
| 0x4 | | 0x4 | ||
| TextFileSize | | TextFileSize (.text compressed size) | ||
|- | |- | ||
| 0x64 | | 0x64 | ||
| 0x4 | | 0x4 | ||
| RoFileSize | | RoFileSize (.rodata compressed size) | ||
|- | |- | ||
| 0x68 | | 0x68 | ||
| 0x4 | | 0x4 | ||
| DataFileSize | | DataFileSize (.data compressed size) | ||
|- | |||
| 0x6C | |||
| 0x1C | |||
| Reserved | |||
|- | |- | ||
| | | 0x88 | ||
| | | 0x4 | ||
| | | EmbeddedOffset (relative to the .rodata section) | ||
|- | |||
| 0x8C | |||
| 0x4 | |||
| EmbeddedSize | |||
|- | |- | ||
| 0x90 | | 0x90 | ||
| | | 0x4 | ||
| .rodata- | | DynStrOffset (relative to the .rodata section) | ||
|- | |||
| 0x94 | |||
| 0x4 | |||
| DynStrSize | |||
|- | |- | ||
| 0x98 | | 0x98 | ||
| | | 0x4 | ||
| .rodata- | | DynSymOffset (relative to the .rodata section) | ||
|- | |||
| 0x9C | |||
| 0x4 | |||
| DynSymSize | |||
|- | |- | ||
| 0xA0 | | 0xA0 | ||
| 0x20 | | 0x20 | ||
| | | TextHash (SHA-256 hash over the decompressed .text section using the above size) | ||
|- | |||
| 0xC0 | |||
| 0x20 | |||
| RoHash (SHA-256 hash over the decompressed .rodata section using the above size) | |||
|- | |||
| 0xE0 | |||
| 0x20 | |||
| DataHash (SHA-256 hash over the decompressed .data section using the above size) | |||
|- | |- | ||
| 0x100 | | 0x100 | ||
| | | Variable | ||
| Compressed sections | | Compressed sections | ||
|} | |} | ||
== Flags == | |||
=== | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
! | ! Bits | ||
! Description | ! Description | ||
|- | |- | ||
| | | 0 | ||
| | | TextCompress (.text section is compressed) | ||
| | |- | ||
| 1 | |||
| RoCompress (.rodata section is compressed) | |||
|- | |||
| 2 | |||
| DataCompress (.data section is compressed) | |||
|- | |- | ||
| | | 3 | ||
| | | TextHash (.text hash must be checked when loading) | ||
|- | |- | ||
| 4 | | 4 | ||
| | | RoHash (.rodata hash must be checked when loading) | ||
|- | |- | ||
| | | 5 | ||
| 4 | | DataHash (.data hash must be checked when loading) | ||
| | |} | ||
== ModuleId == | |||
This is "nn::ro::detail::ModuleId". | |||
Value of "build id" from ELF's GNU .note section. Contains variable sized digest, up to 32bytes. | |||
= Arguments = | |||
[[Loader_services|Loader]] maps memory and writes the [[Loader_services#SetProgramArgument|arguments]] to {end of rwdata section}. Official processes use argdata_addr = {page-aligned _end}. svcQueryMemory is used by official sw to verify that argdata_addr is mapped RW, since this memory is only mapped when arguments are specified via that command. Afterwards, official sw aligns the argdata_addr to 4-bytes. | |||
The structure located at argdata_addr is as follows: | |||
{| class="wikitable" border="1" | |||
|- | |- | ||
! Offset | |||
! Size | |||
! Description | |||
|- | |- | ||
| | | 0x0 || 0x4 || This is the total allocated space relative to argdata_addr, used for calculating the max size of the argv ptr array. Normally 0x9000? | ||
| | |||
| . | |||
|- | |- | ||
| | | 0x4 || 0x4 || This is the total_bytesize of the actual argdata string. | ||
| | |||
| . | |||
|- | |- | ||
| | | 0x8 || 0x18 || Unused by official sw. | ||
| | |||
| . | |||
|- | |- | ||
| 0x20 | | 0x20 || See above || Actual argdata string. | ||
| | |||
| | |||
|} | |} | ||
* The copy of the args used with the argv array is written by official processes to actual_argdata_string+actual_argdata_size. | |||
* argv_ptrarray written by official processes is at (args_copy+actual_argdata_size) + 0x9 & ~0x7. |