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):
| Offset
|
Size
|
Description
|
| 0x0
|
4
|
file offset of data
|
| 0x4
|
4
|
memory offset loaded to
|
| 0x8
|
4
|
size of data copied to memory offset (i.e. size after decompression)
|
| 0xC
|
4
|
alignment used on memory size / size of .bss in the case of .data segment
|
.rodata-relative extent
| Offset
|
Size
|
Description
|
| 0x0
|
4
|
offset (relative to .rodata)
|
| 0x4
|
4
|
size of region
|
| Offset
|
Size
|
Description
|
| 0x0
|
4
|
Magic "NSO0"
|
| 0x4
|
4
|
|
| 0x8
|
4
|
|
| 0xC
|
4
|
|
| 0x10
|
0x10 * 3
|
SegmentHeader for each segment
|
| 0x40
|
0x14
|
Value of "build id" from ELF's GNU .note section
|
| 0x54
|
0xC
|
Padding
|
| 0x60
|
0x4 * 3
|
file size of each segment (i.e. LZ4-compressed size)
|
| 0x6c
|
0x24
|
Padding
|
| 0x90
|
8
|
.rodata-relative extents of .dynstr
|
| 0x98
|
8
|
.rodata-relative extents of .dynsym
|
| 0xA0
|
0x20 * 3
|
SHA256 hashes over the decompressed sections using the above byte-sizes: .text, .rodata, and .data.
|
| 0x100
|
|
Compressed sections
|