private static void DisassembleTasks(RomVersion ver, List <DisassemblyTask> taskList, Func <FileAddress, Stream> getFile) { var folder = GetFolder(ver); Console.CursorVisible = false; foreach (var task in taskList) { string filename = $"{folder}/{task.Name}.txt"; Console.Write($"\r{filename.PadRight(Console.BufferWidth)}"); var file = getFile(task.VRom); foreach (var action in task.PreparseActions) { action(file); } foreach (var item in task.Functions) { Disassemble.AddFunction(item); } using var br = new BinaryReader(file); Disassemble.FirstParse(br, task); using var sw = File.CreateText(filename); Disassemble.Task(sw, br, task); } Console.CursorVisible = true; }
static void DisassembleRom(RomVersion version, string path, Func <DisassemblyTask, bool> filter) { Console.WriteLine($"{version} {path}"); Console.Write("Initializing task list: "); Rom rom = Rom.New(path, version); List <DisassemblyTask> taskList = DisassemblyTask.CreateTaskList(rom); taskList = taskList.Where(filter).Where(x => x.VRom.End > 0).ToList(); if (taskList.Count == 0) { Console.WriteLine("Error: No tasks to process!"); return; } Console.WriteLine("DONE!"); Console.Write($"Loading symbol table from file: "); LoadFunctionDatabase(version); Console.WriteLine("DONE!"); Console.WriteLine("Disassembling files: "); Stream getFile(FileAddress x) => rom.Files.GetFile(x); DisassembleTasks(rom.Version, taskList, getFile); DumpFoundFunctions(rom.Version, Disassemble.GetFunctions()); }
private static int TryDisassemble(DisassemblyOptions opts, Func <RomVersion, string, Func <DisassemblyTask, bool> > getFilter) { string path; if (!RomVersion.TryGet(opts.GameId, opts.VersionId, out RomVersion version)) { Console.WriteLine($"Unrecognized version {opts.GameId} {opts.VersionId}"); return(-1); } if (opts.RomPath != null) { path = opts.RomPath; } else if (!PathUtil.TryGetRomLocation(version, out path)) { Console.WriteLine($"Cannot find path for {opts.GameId} {opts.VersionId}"); return(-1); } Disassemble.MipsToC = opts.MipsToCOutput; Disassemble.GccOutput = Disassemble.MipsToC || !opts.ReadableOutput; Disassemble.PrintRelocations = true; Disassemble.SetGprNames(); Func <DisassemblyTask, bool> filter = getFilter(version, path); if (filter == null) { return(-1); } DisassembleRom(version, path, filter); return(0); }
private static void DisassembleTasks(RomVersion ver, List <DisassemblyTask> taskList, Func <FileAddress, Stream> getFile) { var folder = GetFolder(ver); Console.CursorVisible = false; foreach (var task in taskList) { string filename = $"{folder}/{task.Name}.txt"; Console.Write($"\r{filename.PadRight(Console.BufferWidth)}"); using (StreamWriter sw = new StreamWriter(new FileStream(filename, FileMode.Create, FileAccess.Write))) { var reader = new BinaryReader(getFile(task.VRom)); if (Disassemble.GccOutput) { sw.WriteLine("#include <mips.h>"); sw.WriteLine(".set noreorder"); sw.WriteLine(".set noat"); sw.WriteLine(); } Disassemble.Task(sw, reader, task); } } Console.CursorVisible = true; }
static void DisassembleRom(RomVersion ver, string path) { Rom rom; Console.Write("Initializing task list: "); if (ver.Game == Game.OcarinaOfTime) { rom = new ORom(path, ver); } else { rom = new MRom(path, ver); } List <DisassemblyTask> taskList = DisassemblyTask.CreateTaskList(rom); taskList = taskList.Where(x => x.VRom.End > 0).ToList(); Console.WriteLine("DONE!"); Console.Write($"Building symbol table: "); Stream getFile(FileAddress x) => rom.Files.GetFile(x); LoadFunctionDatabase(ver); GetSymbols(taskList, rom.Version, getFile); Console.WriteLine("DONE!"); Console.WriteLine("Disassembling files: "); DisassembleTasks(rom.Version, taskList, getFile); DumpFoundFunctions(rom.Version, Disassemble.GetFunctions()); }
static void OverlayTest(RomVersion ver, string testOvl) { PathUtil.TryGetRomLocation(ver, out string path); Rom rom = Rom.New(path, ver); var tasks = DisassemblyTask.CreateTaskList(rom); Disassemble.PrintRelocations = true; Disassemble.GccOutput = true; var task = tasks.SingleOrDefault(x => x.Name == testOvl || x.Name == $"ovl_{testOvl}"); if (task == null) { Console.WriteLine("Cannot find overlay"); return; } //var taskbss = tasks.Where(x => x.Sections["bss"]?.Size > 0).ToList(); var reader = new BinaryReader(rom.Files.GetFile(task.VRom)); //using (StreamWriter sw = new StreamWriter("__test.txt")) //{ // foreach (var rel in task.Map.Relocations.Where(x => x.SectionId == Overlay.RelocationWord.Section.text)) // { // reader.BaseStream.Position = rel.Offset; // sw.WriteLine($"{rel.Offset:X6}: {rel.RelocType} {GetOP(reader.ReadBigInt32())}"); // } //} using (StreamWriter sw = new StreamWriter($"__{testOvl}.txt")) { BinaryReader br = new BinaryReader(rom.Files.GetFile(task.VRom)); Disassemble.FirstParse(br, task); if (Disassemble.GccOutput) { sw.WriteLine("#include <mips.h>"); sw.WriteLine(".set noreorder"); sw.WriteLine(".set noat"); sw.WriteLine(); } Disassemble.Task(sw, br, task); } using (StreamWriter sw = new StreamWriter($"__{testOvl}_f.txt")) { foreach (var item in Disassemble.Symbols.OrderBy(x => x.Key)) { sw.WriteLine($"{item.Value.ToString()} = 0x{item.Key}"); } } }
static void MMDebugTest() { RomVersion ver = MRom.Build.DBG; PathUtil.TryGetRomLocation(ver, out string path); Rom rom = new MRom(path, ver); DisassemblyTask task = null; Disassemble.PrintRelocations = true; using StreamWriter sw = File.CreateText("__code.txt"); using BinaryReader br = new BinaryReader(rom.Files.GetFile(task.VRom)); Disassemble.FirstParse(br, task); Disassemble.Task(sw, br, task); }
private static void GetSymbols(List <DisassemblyTask> tasks, RomVersion ver, Func <FileAddress, Stream> getFile) { foreach (var task in tasks) { BinaryReader FileReader = new BinaryReader(getFile(task.VRom)); foreach (var item in task.Functions) { Disassemble.AddFunction(item); } //Get a list of function names Disassemble.FirstParse(FileReader, task); } }
private static void LoadFunctionDatabase(RomVersion version) { var funcInfo = JQuery.GetFunctionInfo(version); Disassemble.AddFunctions(funcInfo); }