mirror of
https://github.com/patchzyy/wiicompiled
synced 2026-09-10 17:16:47 -04:00
181 lines
6.6 KiB
C#
181 lines
6.6 KiB
C#
using System;
|
|
using System.IO;
|
|
using Translator.Core;
|
|
using Translator.Core.CodeGen;
|
|
using Translator.Core.Parsing.Dol;
|
|
using Translator.Core.Parsing.Rel;
|
|
using Xunit;
|
|
|
|
namespace Translator.Tests;
|
|
|
|
public class SdaAndGeneratorTests
|
|
{
|
|
[Fact]
|
|
public void RuntimeConfigGeneratorEmitsConfiguredConstants()
|
|
{
|
|
const uint entry = 0x80006000;
|
|
var dol = SyntheticDolFactory.Create(
|
|
entry,
|
|
sections:
|
|
[
|
|
SyntheticDolFactory.Text(0, entry, 0x60000000)
|
|
]);
|
|
|
|
var tempDir = Path.Combine(Path.GetTempPath(), "mkw_runtime_config_tests");
|
|
Directory.CreateDirectory(tempDir);
|
|
var output = Path.Combine(tempDir, "RuntimeConfig.generated.h");
|
|
|
|
RuntimeConfigGenerator.GenerateConfigHeader(0x8038F780u, 0x8038E9C8u, output);
|
|
var text = File.ReadAllText(output);
|
|
|
|
Assert.Contains("constexpr uint32_t SDA1_BASE = 0x8038F780u;", text);
|
|
Assert.Contains("constexpr uint32_t SDA2_BASE = 0x8038E9C8u;", text);
|
|
}
|
|
|
|
[Fact]
|
|
public void RuntimeConfigGeneratorDoesNotRewriteIdenticalContent()
|
|
{
|
|
const uint entry = 0x80006000;
|
|
var dol = SyntheticDolFactory.Create(
|
|
entry,
|
|
sections:
|
|
[
|
|
SyntheticDolFactory.Text(0, entry, 0x60000000)
|
|
]);
|
|
|
|
var tempDir = Path.Combine(Path.GetTempPath(), "mkw_runtime_config_write_tests");
|
|
Directory.CreateDirectory(tempDir);
|
|
var output = Path.Combine(tempDir, "RuntimeConfig.generated.h");
|
|
|
|
RuntimeConfigGenerator.GenerateConfigHeader(0x8038F780u, 0x8038E9C8u, output);
|
|
var sentinel = new DateTime(2001, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
File.SetLastWriteTimeUtc(output, sentinel);
|
|
|
|
RuntimeConfigGenerator.GenerateConfigHeader(0x8038F780u, 0x8038E9C8u, output);
|
|
|
|
Assert.Equal(sentinel, File.GetLastWriteTimeUtc(output));
|
|
}
|
|
|
|
[Fact]
|
|
public void DataSectionGeneratorEmbedsDolAndRelSections()
|
|
{
|
|
var dol = SyntheticDolFactory.Create(
|
|
0x80004000,
|
|
bssAddress: 0x80009000,
|
|
bssSize: 0x40,
|
|
sections:
|
|
[
|
|
SyntheticDolFactory.Text(0, 0x80004000, 0x60000000),
|
|
SyntheticDolFactory.Data(5, 0x80008000, 0xAA, 0xBB, 0xCC)
|
|
]);
|
|
|
|
var rel = new RelImage(new byte[] { 0x11, 0x22, 0x33 }, 0x80510000);
|
|
var tempDir = Path.Combine(Path.GetTempPath(), "mkw_data_section_tests");
|
|
Directory.CreateDirectory(tempDir);
|
|
var output = Path.Combine(tempDir, "data_sections_init_test.cpp");
|
|
|
|
DataSectionGenerator.Generate(dol, rel, output);
|
|
var text = File.ReadAllText(output);
|
|
|
|
Assert.Contains("kData__data", text);
|
|
Assert.Contains("kData_rel_module", text);
|
|
Assert.Contains("InitializeDataSections", text);
|
|
Assert.Contains("g_dataInitialized", text);
|
|
Assert.Contains("0x80008000", text);
|
|
Assert.Contains("0x80510000", text);
|
|
}
|
|
|
|
[Fact]
|
|
public void DataSectionGeneratorDoesNotEmitRuntimeBssClearAfterInitializedSections()
|
|
{
|
|
var dol = SyntheticDolFactory.Create(
|
|
0x80004000,
|
|
bssAddress: 0x80008000,
|
|
bssSize: 0x100,
|
|
sections:
|
|
[
|
|
SyntheticDolFactory.Data(5, 0x80008020, 0x41, 0x20, 0x00, 0x00)
|
|
]);
|
|
|
|
var tempDir = Path.Combine(Path.GetTempPath(), "mkw_data_section_bss_overlap_tests");
|
|
Directory.CreateDirectory(tempDir);
|
|
var output = Path.Combine(tempDir, "data_sections_init_overlap_test.cpp");
|
|
|
|
DataSectionGenerator.Generate(dol, rel: null, output);
|
|
var text = File.ReadAllText(output);
|
|
|
|
Assert.Contains("0x80008020", text);
|
|
Assert.Contains("BSS section @ 0x80008000 (256 bytes) - memory already zero-initialized", text);
|
|
Assert.DoesNotContain("std::memset", text);
|
|
}
|
|
|
|
[Fact]
|
|
public void DataSectionGeneratorCanWriteStagedBlobsWithFinalIncbinReferences()
|
|
{
|
|
var dol = SyntheticDolFactory.Create(
|
|
0x80004000,
|
|
sections:
|
|
[
|
|
SyntheticDolFactory.Data(5, 0x80008000, 0xAA, 0xBB, 0xCC)
|
|
]);
|
|
var tempDir = Path.Combine(Path.GetTempPath(), $"mkw_data_section_staging_{Guid.NewGuid():N}");
|
|
try
|
|
{
|
|
var stagedDirectory = Path.Combine(tempDir, "staging");
|
|
var finalBlobDirectory = Path.Combine(tempDir, "published", "data_sections_init_blobs");
|
|
var output = Path.Combine(stagedDirectory, "data_sections_init.cpp");
|
|
|
|
DataSectionGenerator.Generate(
|
|
dol,
|
|
rel: null,
|
|
output,
|
|
blobReferenceDirectory: finalBlobDirectory);
|
|
|
|
var assembly = File.ReadAllText(Path.Combine(stagedDirectory, "data_sections_init_blobs.S"));
|
|
var expectedReference = Path.GetFullPath(Path.Combine(finalBlobDirectory, "_data.bin")).Replace('\\', '/');
|
|
Assert.Contains($".incbin \"{expectedReference}\"", assembly, StringComparison.Ordinal);
|
|
Assert.True(File.Exists(Path.Combine(stagedDirectory, "data_sections_init_blobs", "_data.bin")));
|
|
Assert.False(File.Exists(Path.Combine(finalBlobDirectory, "_data.bin")));
|
|
}
|
|
finally
|
|
{
|
|
if (Directory.Exists(tempDir))
|
|
{
|
|
Directory.Delete(tempDir, recursive: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void DataSectionGeneratorChangesAssemblyWhenSameSizeBlobContentChanges()
|
|
{
|
|
var tempDir = Path.Combine(Path.GetTempPath(), $"mkw_data_section_hash_{Guid.NewGuid():N}");
|
|
try
|
|
{
|
|
var output = Path.Combine(tempDir, "data_sections_init.cpp");
|
|
var first = SyntheticDolFactory.Create(
|
|
0x80004000,
|
|
sections: [SyntheticDolFactory.Data(5, 0x80008000, 1, 2, 3, 4)]);
|
|
DataSectionGenerator.Generate(first, rel: null, output);
|
|
var assemblyPath = Path.Combine(tempDir, "data_sections_init_blobs.S");
|
|
var before = File.ReadAllText(assemblyPath);
|
|
|
|
var second = SyntheticDolFactory.Create(
|
|
0x80004000,
|
|
sections: [SyntheticDolFactory.Data(5, 0x80008000, 1, 2, 3, 5)]);
|
|
DataSectionGenerator.Generate(second, rel: null, output);
|
|
var after = File.ReadAllText(assemblyPath);
|
|
|
|
Assert.NotEqual(before, after);
|
|
Assert.Contains("sha256=", after, StringComparison.Ordinal);
|
|
}
|
|
finally
|
|
{
|
|
if (Directory.Exists(tempDir))
|
|
{
|
|
Directory.Delete(tempDir, recursive: true);
|
|
}
|
|
}
|
|
}
|
|
}
|