Difference between revisions of "NPDM"
(16 intermediate revisions by 5 users not shown) | |||
Line 29: | Line 29: | ||
| 0x0 | | 0x0 | ||
| 0x4 | | 0x4 | ||
− | | | + | | Magic ("META") |
|- | |- | ||
| 0x4 | | 0x4 | ||
| 0x4 | | 0x4 | ||
− | | [9.0.0+] | + | | [9.0.0+] SignatureKeyGeneration |
|- | |- | ||
| 0x8 | | 0x8 | ||
Line 113: | Line 113: | ||
|- | |- | ||
| 4 | | 4 | ||
− | | OptimizeMemoryAllocation | + | | [7.0.0+] OptimizeMemoryAllocation |
+ | |- | ||
+ | | 5 | ||
+ | | [11.0.0+] DisableDeviceAddressSpaceMerge | ||
+ | |- | ||
+ | | 6 | ||
+ | | [18.0.0+] EnableAliasRegionExtraSize | ||
+ | |- | ||
+ | | 7 | ||
+ | | [19.0.0+] PreventCodeReads | ||
|} | |} | ||
Line 120: | Line 129: | ||
== SystemResourceSize == | == SystemResourceSize == | ||
− | This | + | When this is non-zero, the kernel reserves this amount of memory and dynamically uses it as needed for page table pages, KMemoryBlocks, and KBlockInfos. When this is zero, the process uses global shared heaps for these. |
+ | |||
+ | This enables a process to sacrifice some of the memory available to it in order to have higher limits on these resources, thus enabling the use of SvcMapPhysicalMemory. | ||
+ | |||
+ | Maximum size as is 0x1FE00000. | ||
+ | |||
== Version == | == Version == | ||
Line 130: | Line 144: | ||
== MainThreadStackSize == | == MainThreadStackSize == | ||
− | Must be aligned to 0x1000. | + | Must be aligned to 0x1000. If zero, kernel will start the process's initial thread with sp=0. |
− | |||
− | |||
= ACID = | = ACID = | ||
Line 151: | Line 163: | ||
| 0x200 | | 0x200 | ||
| 0x4 | | 0x4 | ||
− | | | + | | Magic ("ACID") |
|- | |- | ||
| 0x204 | | 0x204 | ||
Line 158: | Line 170: | ||
|- | |- | ||
| 0x208 | | 0x208 | ||
− | | | + | | 0x1 |
+ | | [9.0.0+] Version | ||
+ | |- | ||
+ | | 0x209 | ||
+ | | 0x1 | ||
+ | | [14.0.0+] | ||
+ | |- | ||
+ | | 0x20A | ||
+ | | 0x2 | ||
| Reserved | | Reserved | ||
|- | |- | ||
Line 175: | Line 195: | ||
| 0x220 | | 0x220 | ||
| 0x4 | | 0x4 | ||
− | | [[#FsAccessControl| | + | | [[#FsAccessControl|FacOffset]] |
|- | |- | ||
| 0x224 | | 0x224 | ||
| 0x4 | | 0x4 | ||
− | | [[#FsAccessControl| | + | | [[#FsAccessControl|FacSize]] |
|- | |- | ||
| 0x228 | | 0x228 | ||
| 0x4 | | 0x4 | ||
− | | [[#SrvAccessControl| | + | | [[#SrvAccessControl|SacOffset]] |
|- | |- | ||
| 0x22C | | 0x22C | ||
| 0x4 | | 0x4 | ||
− | | [[#SrvAccessControl| | + | | [[#SrvAccessControl|SacSize]] |
|- | |- | ||
| 0x230 | | 0x230 | ||
| 0x4 | | 0x4 | ||
− | | [[#KernelCapability| | + | | [[#KernelCapability|KcOffset]] |
|- | |- | ||
| 0x234 | | 0x234 | ||
| 0x4 | | 0x4 | ||
− | | [[#KernelCapability| | + | | [[#KernelCapability|KcSize]] |
|- | |- | ||
| 0x238 | | 0x238 | ||
Line 214: | Line 234: | ||
| UnqualifiedApproval | | UnqualifiedApproval | ||
|- | |- | ||
− | | 2- | + | | 2-5 |
− | | [5.0.0+ ] MemoryRegion (0 = Application, 1 = Applet, 2 = SecureSystem, 3 = NonSecureSystem) | + | | [5.0.0+] MemoryRegion (0 = Application, 1 = Applet, 2 = SecureSystem, 3 = NonSecureSystem) |
|} | |} | ||
Line 229: | Line 249: | ||
| 0x0 | | 0x0 | ||
| 0x4 | | 0x4 | ||
− | | | + | | Magic ("ACI0") |
|- | |- | ||
| 0x4 | | 0x4 | ||
Line 245: | Line 265: | ||
| 0x20 | | 0x20 | ||
| 0x4 | | 0x4 | ||
− | | [[#FsAccessControl| | + | | [[#FsAccessControl|FacOffset]] |
|- | |- | ||
| 0x24 | | 0x24 | ||
| 0x4 | | 0x4 | ||
− | | [[#FsAccessControl| | + | | [[#FsAccessControl|FacSize]] |
|- | |- | ||
| 0x28 | | 0x28 | ||
| 0x4 | | 0x4 | ||
− | | [[#SrvAccessControl| | + | | [[#SrvAccessControl|SacOffset]] |
|- | |- | ||
| 0x2C | | 0x2C | ||
| 0x4 | | 0x4 | ||
− | | [[#SrvAccessControl| | + | | [[#SrvAccessControl|SacSize]] |
|- | |- | ||
| 0x30 | | 0x30 | ||
| 0x4 | | 0x4 | ||
− | | [[#KernelCapability| | + | | [[#KernelCapability|KcOffset]] |
|- | |- | ||
| 0x34 | | 0x34 | ||
| 0x4 | | 0x4 | ||
− | | [[#KernelCapability| | + | | [[#KernelCapability|KcSize]] |
|- | |- | ||
| 0x38 | | 0x38 | ||
Line 285: | Line 305: | ||
|- | |- | ||
| 0x1 | | 0x1 | ||
+ | | 0x1 | ||
+ | | [5.0.0+] ContentOwnerIdCount | ||
+ | |- | ||
+ | | 0x2 | ||
+ | | 0x1 | ||
+ | | [5.0.0+] SaveDataOwnerIdCount | ||
+ | |- | ||
| 0x3 | | 0x3 | ||
+ | | 0x1 | ||
| Padding | | Padding | ||
|- | |- | ||
Line 293: | Line 321: | ||
|- | |- | ||
| 0xC | | 0xC | ||
− | | | + | | 0x8 |
− | | | + | | ContentOwnerIdMin |
+ | |- | ||
+ | | 0x14 | ||
+ | | 0x8 | ||
+ | | ContentOwnerIdMax | ||
+ | |- | ||
+ | | 0x1C | ||
+ | | 0x8 | ||
+ | | SaveDataOwnerIdMin | ||
+ | |- | ||
+ | | 0x24 | ||
+ | | 0x8 | ||
+ | | SaveDataOwnerIdMax | ||
+ | |- | ||
+ | | 0x2C | ||
+ | | 0x8 * ContentOwnerIdCount | ||
+ | | [5.0.0+] ContentOwnerIds | ||
+ | |- | ||
+ | | Variable | ||
+ | | 0x8 * SaveDataOwnerIdCount | ||
+ | | [5.0.0+] SaveDataOwnerIds | ||
|} | |} | ||
Line 334: | Line 382: | ||
| 0x1C | | 0x1C | ||
| 0x4 | | 0x4 | ||
− | | (Optional) | + | | (Optional) ContentOwnerIdCount |
|- | |- | ||
| 0x1C | | 0x1C | ||
− | | 0x8 * | + | | 0x8 * ContentOwnerIdCount |
− | | | + | | ContentOwnerIds |
|- | |- | ||
| Variable | | Variable | ||
| 0x4 | | 0x4 | ||
− | | | + | | SaveDataOwnerIdCount |
|- | |- | ||
| Variable | | Variable | ||
− | | 0x1 * | + | | 0x1 * SaveDataOwnerIdCount |
− | | | + | | Accessibilities (1=Read, 2=Write, 3=ReadWrite) |
|- | |- | ||
| Variable (padded to nearest 4 bytes) | | Variable (padded to nearest 4 bytes) | ||
− | | 0x8 * | + | | 0x8 * SaveDataOwnerIdCount |
− | | | + | | SaveDataOwnerIds |
|} | |} | ||
Line 504: | Line 552: | ||
| | | | ||
|- | |- | ||
− | | 36-61 | + | | 36 |
+ | | MoveCacheStorage | ||
+ | | | ||
+ | |- | ||
+ | | 37 | ||
+ | | DeviceTreeBlob | ||
+ | | | ||
+ | |- | ||
+ | | 38 | ||
+ | | NotifyErrorContextServiceReady | ||
+ | | | ||
+ | |- | ||
+ | | 39-61 | ||
| Reserved | | Reserved | ||
| | | | ||
Line 592: | Line 652: | ||
| All ones | | All ones | ||
| | | | ||
− | | | + | | Invalid |
|} | |} | ||
Line 630: | Line 690: | ||
== MemoryMap == | == MemoryMap == | ||
+ | MemoryMap entries are stored in pairs. The first pair will contain BeginAddress and PermissionType, while the second pair will contain Size and MappingType. | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 636: | Line 697: | ||
|- | |- | ||
| 7-30 | | 7-30 | ||
− | | BeginAddress | + | | BeginAddress |
|- | |- | ||
| 31 | | 31 | ||
− | | | + | | PermissionType (0=RW, 1=RO) |
|} | |} | ||
− | + | {| class="wikitable" border="1" | |
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 7-26 | ||
+ | | Size | ||
+ | |- | ||
+ | | 27-30 | ||
+ | | Reserved | ||
+ | |- | ||
+ | | 31 | ||
+ | | MappingType (0=Io, 1=Static) | ||
+ | |} | ||
=== Restrictions === | === Restrictions === | ||
Line 695: | Line 769: | ||
| RegionIsReadOnly2 | | RegionIsReadOnly2 | ||
|} | |} | ||
− | |||
− | |||
== EnableInterrupts == | == EnableInterrupts == | ||
Line 738: | Line 810: | ||
|} | |} | ||
− | This is | + | This encodes the intended kernel version for the program. |
+ | |||
+ | The kernel requires that the intended version is >= the minimum supported version (3.0 for all released kernels), and <= the current version. | ||
+ | |||
+ | Kernel version is derived from/equivalent to SDK version: | ||
+ | * Kernel Major = SDK Major + 4 | ||
+ | * Kernel Minor = SDK Minor | ||
=== Versions === | === Versions === | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
− | ! Firmware || Kernel Version || | + | ! Firmware || Kernel Version || Corresponding SDK Version |
+ | |- | ||
+ | | 1.0.0 || 5.0 || 1.0.0.0 | ||
|- | |- | ||
− | | | + | | 2.0.0 || 6.1 || 2.1.0.0 |
|- | |- | ||
− | | | + | | 3.0.0 || 7.4 || 3.4.0.0 |
|- | |- | ||
− | | 3.0. | + | | 3.0.2 || 7.4 || 3.4.0.0 |
|- | |- | ||
− | | | + | | 5.0.0 || 9.3 || 5.3.0.0 |
|- | |- | ||
− | | | + | | 10.0.0 || 14.4 || 10.4.0.0 |
+ | |- | ||
+ | | 11.0.0 || 15.4 || 11.4.0.0 | ||
+ | |- | ||
+ | | 11.0.1 || 15.4 || 11.4.0.0 | ||
|} | |} | ||
Line 776: | Line 860: | ||
|- | |- | ||
| 18 | | 18 | ||
− | | ForceDebug | + | | [19.0.0+] ForceDebugProd ([1.0.0-18.1.0] ForceDebug) |
+ | |- | ||
+ | | 19 | ||
+ | | [19.0.0+] ForceDebug | ||
|} | |} |
Latest revision as of 22:16, 23 October 2024
This is the Switch equivalent of 3DS exheader. This is the file with extension ".npdm" in {Switch ExeFS}. The size of this file varies.
Offset | Size | Description |
---|---|---|
0x0 | 0x80 | META |
0x80 | <Varies> | ACID |
<See META> | <See META> | ACI0 |
META
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Magic ("META") |
0x4 | 0x4 | [9.0.0+] SignatureKeyGeneration |
0x8 | 0x4 | Reserved |
0xC | 0x1 | Flags |
0xD | 0x1 | Reserved |
0xE | 0x1 | MainThreadPriority |
0xF | 0x1 | MainThreadCoreNumber |
0x10 | 0x4 | Reserved |
0x14 | 0x4 | [3.0.0+] SystemResourceSize |
0x18 | 0x4 | Version |
0x1C | 0x4 | MainThreadStackSize |
0x20 | 0x10 | Name (usually/always "Application") |
0x30 | 0x10 | ProductCode (usually/always all zeroes) |
0x40 | 0x30 | Reserved |
0x70 | 0x4 | AciOffset |
0x74 | 0x4 | AciSize |
0x78 | 0x4 | AcidOffset |
0x7C | 0x4 | AcidSize |
Flags
Bits | Description |
---|---|
0 | Is64BitInstruction |
1-3 | ProcessAddressSpace (0x00 = AddressSpace32Bit, 0x01 = AddressSpace64BitOld, 0x02 = AddressSpace32BitNoReserved, 0x03 = AddressSpace64Bit) |
4 | [7.0.0+] OptimizeMemoryAllocation |
5 | [11.0.0+] DisableDeviceAddressSpaceMerge |
6 | [18.0.0+] EnableAliasRegionExtraSize |
7 | [19.0.0+] PreventCodeReads |
MainThreadPriority
Ranges from 0 to 0x3F.
SystemResourceSize
When this is non-zero, the kernel reserves this amount of memory and dynamically uses it as needed for page table pages, KMemoryBlocks, and KBlockInfos. When this is zero, the process uses global shared heaps for these.
This enables a process to sacrifice some of the memory available to it in order to have higher limits on these resources, thus enabling the use of SvcMapPhysicalMemory.
Maximum size as is 0x1FE00000.
Version
0 for all titles.
[8.1.0+] Now set to 1 for certain titles.
[9.0.0+] Now set to a proper version field for all titles.
MainThreadStackSize
Must be aligned to 0x1000. If zero, kernel will start the process's initial thread with sp=0.
ACID
Offset | Size | Description |
---|---|---|
0x0 | 0x100 | RSA-2048 signature over the data starting at 0x100 with the size field from 0x204 |
0x100 | 0x100 | RSA-2048 public key for the second NCA signature |
0x200 | 0x4 | Magic ("ACID") |
0x204 | 0x4 | Size |
0x208 | 0x1 | [9.0.0+] Version |
0x209 | 0x1 | [14.0.0+] |
0x20A | 0x2 | Reserved |
0x20C | 0x4 | Flags |
0x210 | 0x8 | ProgramIdMin |
0x218 | 0x8 | ProgramIdMax |
0x220 | 0x4 | FacOffset |
0x224 | 0x4 | FacSize |
0x228 | 0x4 | SacOffset |
0x22C | 0x4 | SacSize |
0x230 | 0x4 | KcOffset |
0x234 | 0x4 | KcSize |
0x238 | 0x8 | Reserved |
Flags
Bits | Description |
---|---|
0 | ProductionFlag |
1 | UnqualifiedApproval |
2-5 | [5.0.0+] MemoryRegion (0 = Application, 1 = Applet, 2 = SecureSystem, 3 = NonSecureSystem) |
MemoryRegion is set to Application for "starter" and NonSecureSystem for "nvservices".
ACI0
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Magic ("ACI0") |
0x4 | 0xC | Reserved |
0x10 | 0x8 | ProgramId |
0x18 | 0x8 | Reserved |
0x20 | 0x4 | FacOffset |
0x24 | 0x4 | FacSize |
0x28 | 0x4 | SacOffset |
0x2C | 0x4 | SacSize |
0x30 | 0x4 | KcOffset |
0x34 | 0x4 | KcSize |
0x38 | 0x8 | Reserved |
FsAccessControl
For ACID this is a simple descriptor as follows:
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | Version (always 1, must be non-zero) |
0x1 | 0x1 | [5.0.0+] ContentOwnerIdCount |
0x2 | 0x1 | [5.0.0+] SaveDataOwnerIdCount |
0x3 | 0x1 | Padding |
0x4 | 0x8 | FsAccessFlag |
0xC | 0x8 | ContentOwnerIdMin |
0x14 | 0x8 | ContentOwnerIdMax |
0x1C | 0x8 | SaveDataOwnerIdMin |
0x24 | 0x8 | SaveDataOwnerIdMax |
0x2C | 0x8 * ContentOwnerIdCount | [5.0.0+] ContentOwnerIds |
Variable | 0x8 * SaveDataOwnerIdCount | [5.0.0+] SaveDataOwnerIds |
For ACI0 this embeds data as follows:
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | Version (always 1, must be non-zero) |
0x1 | 0x3 | Padding |
0x4 | 0x8 | FsAccessFlag |
0xC | 0x4 | ContentOwnerInfoOffset |
0x10 | 0x4 | ContentOwnerInfoSize |
0x14 | 0x4 | SaveDataOwnerInfoOffset |
0x18 | 0x4 | SaveDataOwnerInfoSize |
0x1C | 0x4 | (Optional) ContentOwnerIdCount |
0x1C | 0x8 * ContentOwnerIdCount | ContentOwnerIds |
Variable | 0x4 | SaveDataOwnerIdCount |
Variable | 0x1 * SaveDataOwnerIdCount | Accessibilities (1=Read, 2=Write, 3=ReadWrite) |
Variable (padded to nearest 4 bytes) | 0x8 * SaveDataOwnerIdCount | SaveDataOwnerIds |
FsAccessFlag
Bits | Name | Description |
---|---|---|
0 | ApplicationInfo | MountContent* is accessible when set. |
1 | BootModeControl | |
2 | Calibration | |
3 | SystemSaveData | |
4 | GameCard | |
5 | SaveDataBackUp | |
6 | SaveDataManagement | |
7 | BisAllRaw | |
8 | GameCardRaw | |
9 | GameCardPrivate | |
10 | SetTime | |
11 | ContentManager | |
12 | ImageManager | |
13 | CreateSaveData | |
14 | SystemSaveDataManagement | |
15 | BisFileSystem | |
16 | SystemUpdate | |
17 | SaveDataMeta | |
18 | DeviceSaveData | |
19 | SettingsControl | |
20 | SystemData | |
21 | SdCard | |
22 | Host | |
23 | FillBis | |
24 | CorruptSaveData | |
25 | SaveDataForDebug | |
26 | FormatSdCard | |
27 | GetRightsId | |
28 | RegisterExternalKey | |
29 | RegisterUpdatePartition | |
30 | SaveDataTransfer | |
31 | DeviceDetection | |
32 | AccessFailureResolution | |
33 | SaveDataTransferVersion2 | |
34 | RegisterProgramIndexMapInfo | |
35 | CreateOwnSaveData | |
36 | MoveCacheStorage | |
37 | DeviceTreeBlob | |
38 | NotifyErrorContextServiceReady | |
39-61 | Reserved | |
62 | Debug | See here. |
63 | FullPermission | Enables access to everything: all permission types which check a bitmask have this bit set. |
Controls the filesystem permissions.
Web-applets permissions:
- "LibAppletWeb" and "LibAppletOff" have same access control: bit0 and bit3 set, and bit62 set.
- Rest of the web-applets: Same as above except bit0 isn't set.
Service Access Control
Bits | Description |
---|---|
0-2 | Size (length of the service-name without null-terminator minus 1) |
7 | IsServer (service is allowed to be registered) |
Variable | Name |
This is a list of service-name strings which the title has access to.
The service name string starts after the first byte and supports the wildcard *
character.
KernelCapability
Pattern of lower bits | Lowest clear bitmask/bit | Description |
---|---|---|
0bxxxxxxxxxxxx0111
|
Bit3 | #ThreadInfo |
0bxxxxxxxxxxx01111
|
Bit4 | #EnableSystemCalls |
0bxxxxxxxxx0111111
|
Bit6 | #MemoryMap |
0bxxxxxxxx01111111
|
Bit7 | #IoMemoryMap |
0bxxxxx01111111111
|
Bit10 | [8.0.0+] #MemoryRegionMap |
0bxxxx011111111111
|
Bit11 | #EnableInterrupts |
0bxx01111111111111
|
Bit13 | #MiscParams |
0bx011111111111111
|
Bit14 | #KernelVersion |
0b0111111111111111
|
Bit15 | #HandleTableSize |
0b1111111111111111
|
Bit16 | #MiscFlags |
All ones | Invalid |
These descriptors are identified by pattern 01..11 in low bits.
ThreadInfo
Bits | Description |
---|---|
4-9 | LowestPriority |
10-15 | HighestPriority |
16-23 | MinCoreNumber |
24-31 | MaxCoreNumber |
EnableSystemCalls
Bits | Description |
---|---|
5-28 | SystemCallId |
29-31 | Index |
MemoryMap
MemoryMap entries are stored in pairs. The first pair will contain BeginAddress and PermissionType, while the second pair will contain Size and MappingType.
Bits | Description |
---|---|
7-30 | BeginAddress |
31 | PermissionType (0=RW, 1=RO) |
Bits | Description |
---|---|
7-26 | Size |
27-30 | Reserved |
31 | MappingType (0=Io, 1=Static) |
Restrictions
The physaddr range 0x80060000-0x2000000000 is not allowed to be mapped as IO. The physaddr range 0x80000000-0x2000000000 is not allowed to be mapped as Normal.
[2.0.0-4.1.0] The range for IO was changed into 0x80060000-0x81D3FFFF.
[2.0.0-4.1.0] A blacklist was added for IO and Normal mappings:
- 0x50040000-0x50060000 (ARM, Interrupt Controller)
- 0x6000F000 (Exception Vectors)
- 0x6001DC00-0x6001E000 (IPATCH)
- 0x7000E000 (RTC/PMC)
- 0x70019000 (MC)
- 0x7001C000 (MC0)
- 0x7001D000 (MC1)
[5.0.0+] For IO, this blacklist was abandoned and instead two range checks were added. For Normal mappings it is still applied
IoMemoryMap
Bits | Description |
---|---|
8-31 | BeginAddress |
MemoryRegionMap
Bits | Description |
---|---|
11-16 | RegionType0 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB) |
17 | RegionIsReadOnly0 |
18-23 | RegionType1 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB) |
24 | RegionIsReadOnly1 |
25-30 | RegionType2 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB) |
31 | RegionIsReadOnly2 |
EnableInterrupts
Bits | Description |
---|---|
12-21 | InterruptNumber0 |
22-31 | InterruptNumber1 |
0x3FF means empty.
MiscParams
Bits | Description |
---|---|
14-16 | ProgramType (0 = System, 1 = Application, 2 = Applet) |
ProgramType is parsed by Process Manager services. Defaults to 0 if descriptor doesn't exist. Can only run 1 application at a time.
KernelVersion
Bits | Description |
---|---|
15-18 | MinorVersion |
19-31 | MajorVersion |
This encodes the intended kernel version for the program.
The kernel requires that the intended version is >= the minimum supported version (3.0 for all released kernels), and <= the current version.
Kernel version is derived from/equivalent to SDK version:
- Kernel Major = SDK Major + 4
- Kernel Minor = SDK Minor
Versions
Firmware | Kernel Version | Corresponding SDK Version |
---|---|---|
1.0.0 | 5.0 | 1.0.0.0 |
2.0.0 | 6.1 | 2.1.0.0 |
3.0.0 | 7.4 | 3.4.0.0 |
3.0.2 | 7.4 | 3.4.0.0 |
5.0.0 | 9.3 | 5.3.0.0 |
10.0.0 | 14.4 | 10.4.0.0 |
11.0.0 | 15.4 | 11.4.0.0 |
11.0.1 | 15.4 | 11.4.0.0 |
HandleTableSize
Bits | Description |
---|---|
16-25 | HandleTableSize |
MiscFlags
Bits | Description |
---|---|
17 | EnableDebug |
18 | [19.0.0+] ForceDebugProd ([1.0.0-18.1.0] ForceDebug) |
19 | [19.0.0+] ForceDebug |