Untitled
unknown
csharp
3 years ago
8.6 kB
14
Indexable
private void button29_Click(object sender, EventArgs e)
{
// Open file
string sourcePath;
using (OpenFileDialog dialog = new OpenFileDialog())
{
// If user closes dialog, return to main window
if (dialog.ShowDialog(this) != DialogResult.OK)
{
return;
}
sourcePath = dialog.FileName;
}
string sFile = File.ReadAllText(sourcePath);
string[] xMap = File.ReadAllLines("xmap.txt");
List<string> linkOrderLines = new List<string>();
Regex symbolRegex = new Regex(@"(?<address>[0-9A-F]{8})\s+(?<size>[0-9A-F]{8})\s\.(?<section>text|(ro)*data|bss)\s+(?<name>.+?)\s+\((?<source>.+)\)", RegexOptions.ExplicitCapture | RegexOptions.Compiled);
int overlayNumber = Convert.ToInt32(Path.GetFileNameWithoutExtension(sourcePath).Replace("overlay", ""));
int i = 0;
// Go to overlay section
while (!xMap[i++].Contains($"# .overlay{overlayNumber}"))
continue;
Debug.WriteLine("----- FOUND OVERLAY IN XMAP");
List<Symbol> textSymbols = new List<Symbol>();
List<Symbol> rodataSymbols = new List<Symbol>();
List<Symbol> dataSymbols = new List<Symbol>();
List<Symbol> bssSymbols = new List<Symbol>();
while (!xMap[i++].Contains($"SDK_OVERLAY.overlay{overlayNumber}.BSS_END"))
{
if (symbolRegex.IsMatch(xMap[i]))
{
Match m = symbolRegex.Match(xMap[i]);
Symbol s = new Symbol();
s.address = Convert.ToInt32(m.Groups["address"].Value, 16);
s.size = Convert.ToInt32(m.Groups["size"].Value, 16);
s.section = m.Groups["section"].Value;
s.name = m.Groups["name"].Value.Trim();
s.source = m.Groups["source"].Value.Trim();
s.offset = 0;
Debug.WriteLine(s.source);
if (s.size == 0)
continue;
switch (s.section)
{
case "rodata":
rodataSymbols.Add(s);
break;
case "data":
dataSymbols.Add(s);
break;
case "bss":
bssSymbols.Add(s);
break;
default:
textSymbols.Add(s);
break;
}
}
}
// Fix sizes or offsets
for (i = 0; i < textSymbols.Count - 1; i++)
textSymbols[i].size = textSymbols[i + 1].address - textSymbols[i].address;
for (i = 0; i < rodataSymbols.Count; i++)
{
rodataSymbols[i].offset = rodataSymbols[i].address - rodataSymbols[0].address;
}
for (i = 0; i < dataSymbols.Count; i++)
{
dataSymbols[i].offset = dataSymbols[i].address - dataSymbols[0].address;
}
for (i = 0; i < bssSymbols.Count - 1; i++)
{
bssSymbols[i].size = bssSymbols[i+1].address - bssSymbols[i].address;
}
// Split by file
var textByFile = textSymbols.GroupBy(s => s.source);
var rodataByFile = rodataSymbols.GroupBy(s => s.source);
var dataByFile = dataSymbols.GroupBy(s => s.source);
var bssByFile = bssSymbols.GroupBy(s => s.source);
// Text headers
string textHeader = @" .include ""macros/function.inc""
.include ""global.inc""
.text
";
Debug.WriteLine("TEXT FILES: " + textByFile.Count());
// Write splits
foreach (var textgroup in textByFile)
{
linkOrderLines.Add($"Object asm/ov{overlayNumber}_" + textgroup.First().address.ToString("X8") + ".o");
string functions = Regex.Match(sFile, $@"(thumb|arm)_func_start ov{overlayNumber}_{textgroup.First().address.ToString("X8")}[\w\W]+(thumb|arm)_func_end ov{overlayNumber}_{textgroup.Last().address.ToString("X8")}").Value;
string rodata = "\t.rodata\r\n\r\n";
foreach (var rodatagroup in rodataByFile)
{
if (rodatagroup.Key != textgroup.Key)
continue;
for (int j = 0; j < rodatagroup.Count(); j++)
{
Symbol symbol = rodatagroup.ElementAt(j);
string symbolString = $"Unk_ov{overlayNumber}_{symbol.address.ToString("X8")}: ; 0x{symbol.address.ToString("X8")}\r\n\t";
if (j == 0)
symbolString += $@".incbin ""incbin/overlay{overlayNumber}_rodata.bin"", 0x{symbol.offset.ToString("X")}, 0x{symbol.size.ToString("X")}" + "\r\n";
else if (j == rodatagroup.Count() - 1)
symbolString += $@".incbin ""incbin/overlay{overlayNumber}_rodata.bin"", 0x{symbol.offset.ToString("X")}, 0x{symbol.size.ToString("X")}" + "\r\n";
else
symbolString += $@".incbin ""incbin/overlay{overlayNumber}_rodata.bin"", 0x{symbol.offset.ToString("X")}, 0x{rodatagroup.ElementAt(j+1).offset.ToString("X")} - 0x{symbol.offset.ToString("X")}" + "\r\n";
rodata += symbolString + "\r\n";
}
}
string data = "\t.data\r\n\r\n";
foreach (var datagroup in dataByFile)
{
if (datagroup.Key != textgroup.Key)
continue;
for (int j = 0; j < datagroup.Count(); j++)
{
Symbol symbol = datagroup.ElementAt(j);
string symbolString = $"Unk_ov{overlayNumber}_{symbol.address.ToString("X8")}: ; 0x{symbol.address.ToString("X8")}\r\n\t";
if (j == 0)
symbolString += $@".incbin ""incbin/overlay{overlayNumber}_data.bin"", 0x0, 0x{symbol.size.ToString("X")}" + "\r\n";
else if (j == datagroup.Count() - 1)
symbolString += $@".incbin ""incbin/overlay{overlayNumber}_data.bin"", 0x{symbol.offset.ToString("X")}, 0x{symbol.size.ToString("X")}" + "\r\n";
else
symbolString += $@".incbin ""incbin/overlay{overlayNumber}_data.bin"", 0x{symbol.offset.ToString("X")}, 0x{datagroup.ElementAt(j + 1).offset.ToString("X")} - 0x{symbol.offset.ToString("X")}" + "\r\n";
data += symbolString + "\r\n";
}
}
string bss = "\t.bss\r\n\r\n";
foreach (var bssgroup in bssByFile)
{
if (bssgroup.Key != textgroup.Key)
continue;
for (int j = 0; j < bssgroup.Count(); j++)
{
Symbol symbol = bssgroup.ElementAt(j);
string symbolString = $"Unk_ov{overlayNumber}_{symbol.address.ToString("X8")}: ; 0x{symbol.address.ToString("X8")}\r\n\t";
symbolString += $".space 0x{symbol.size.ToString("X")}" + "\r\n";
bss += symbolString + "\r\n";
}
}
string content = textHeader + "\t" + functions;
if (rodata != "\t.rodata\r\n\r\n")
content += "\r\n\r\n" + rodata;
if (data != "\t.data\r\n\r\n")
content += "\r\n" + data;
if (bss != "\t.bss\r\n\r\n")
content += "\r\n" + bss;
File.WriteAllText($"split\\ov{overlayNumber}_{textgroup.First().address.ToString("X8")}.s", content);
}
File.WriteAllLines($"ov{overlayNumber}_link_order.txt", linkOrderLines);
}Editor is loading...