6internal static class NdsImageValidator
12 public static NdsValidationResult Validate(NdsImage image, NdsValidationOptions options)
14 var diagnostics =
new List<NdsDiagnostic>();
16 diagnostics,
"NDS1001",
"header", image.Header.HeaderCrc,
17 image.Header.RawData.Span[..0x15E],
new(0, 0x160));
19 diagnostics,
"NDS1002",
"Nintendo logo", image.Header.NintendoLogoCrc,
20 image.Header.RawData.Span.Slice(0xC0, 156),
new(0xC0, 156));
22 ValidateRegion(diagnostics, image.Length,
"NDS1101",
"ARM9 program", image.Header.Arm9.Data);
23 ValidateRegion(diagnostics, image.Length,
"NDS1102",
"ARM7 program", image.Header.Arm7.Data);
24 ValidateRegion(diagnostics, image.Length,
"NDS1103",
"filename table", image.Header.FileNameTable);
25 ValidateRegion(diagnostics, image.Length,
"NDS1104",
"file allocation table", image.Header.FileAllocationTable);
26 ValidateRegion(diagnostics, image.Length,
"NDS1105",
"ARM9 overlay table", image.Header.Arm9OverlayTable);
27 ValidateRegion(diagnostics, image.Length,
"NDS1106",
"ARM7 overlay table", image.Header.Arm7OverlayTable);
28 if (image.Header.Arm9i is not
null)
30 ValidateRegion(diagnostics, image.Length,
"NDS1107",
"ARM9i program", image.Header.Arm9i.Data);
33 if (image.Header.Arm7i is not
null)
35 ValidateRegion(diagnostics, image.Length,
"NDS1108",
"ARM7i program", image.Header.Arm7i.Data);
38 ValidateOverlays(diagnostics, image.Arm9Overlays);
39 ValidateOverlays(diagnostics, image.Arm7Overlays);
40 if (image.Banner is not
null)
42 diagnostics.AddRange(image.Banner.ValidateCrcs(image.Header.BannerOffset));
45 NdsSecureAreaValidator.Validate(image, diagnostics, options.SecureAreaKeyTable);
46 NdsDsiIntegrityValidator.Validate(image, diagnostics, options);
48 return new NdsValidationResult(diagnostics);
58 private static void ValidateChecksum(
59 List<NdsDiagnostic> diagnostics,
63 ReadOnlySpan<byte> data,
66 ushort calculated = NdsChecksums.ComputeCrc16(data);
67 if (stored != calculated)
72 $
"The stored {name} CRC is 0x{stored:X4}, but the calculated value is 0x{calculated:X4}.",
83 private static void ValidateRegion(
84 List<NdsDiagnostic> diagnostics,
90 if (region.Offset < 0 || region.Length < 0 || region.Offset > imageLength - region.Length)
95 $
"The {name} region at 0x{region.Offset:X} with length 0x{region.Length:X} is outside the 0x{imageLength:X}-byte image.",
103 private static void ValidateOverlays(List<NdsDiagnostic> diagnostics, IEnumerable<NdsOverlay> overlays)
105 foreach (NdsOverlay overlay
in overlays)
107 if (overlay.Data is
null)
112 $
"{overlay.Processor} overlay {overlay.Id} references missing FAT file ID {overlay.FileId}."));
115 if (overlay.StaticInitializerEnd < overlay.StaticInitializerStart)
120 $
"{overlay.Processor} overlay {overlay.Id} has a reversed static-initializer range."));
NdsDiagnosticSeverity
Indicates the impact of a validation finding.