Skip to content
This repository was archived by the owner on Apr 20, 2018. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 62 additions & 2 deletions smxdasm/File.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
using System.Collections.Generic;

namespace smxdasm
Expand All @@ -22,6 +23,8 @@ public class SmxFile
public SmxDebugNativesTable DebugNatives;
public SmxDebugSymbolsTable DebugSymbols;

public SmxCalledFunctionsTable CalledFunctions;

public SmxFile(BinaryReader br)
{
Header = FileHeader.From(br);
Expand All @@ -36,7 +39,9 @@ public SmxFile(BinaryReader br)
else if (section.Name == ".dbg.info")
DebugInfo = new SmxDebugInfoSection(Header, section);
}


CalledFunctions = new SmxCalledFunctionsTable();

// Parse out other sections.
var unknown = new List<SectionEntry>();
foreach (var section in Header.Sections)
Expand Down Expand Up @@ -83,6 +88,53 @@ public SmxFile(BinaryReader br)
}
}
UnknownSections = unknown.ToArray();

// Disassemble all functions right away to find all called functions.
if (DebugSymbols != null)
{
foreach (var entry in DebugSymbols.Entries)
{
if (entry.Ident != SymKind.Function)
continue;

try
{
V1Disassembler.Disassemble(this, CodeV1, entry.Address);
}
catch (Exception)
{
continue;
}
}
}
if (Publics != null)
{
foreach (var pubfun in Publics.Entries)
{
try
{
V1Disassembler.Disassemble(this, CodeV1, (int)pubfun.Address);
}
catch (Exception)
{
continue;
}
}
}
if (CalledFunctions != null)
{
foreach (var fun in CalledFunctions.Entries)
{
try
{
V1Disassembler.Disassemble(this, CodeV1, (int)fun.Address);
}
catch (Exception)
{
continue;
}
}
}
}

public string FindFunctionName(int address)
Expand All @@ -101,6 +153,14 @@ public string FindFunctionName(int address)
return pubfun.Name;
}
}
if (CalledFunctions != null)
{
foreach (var fun in CalledFunctions.Entries)
{
if (fun.Address == address)
return fun.Name;
}
}
return "(unknown)";
}
}
Expand Down
33 changes: 33 additions & 0 deletions smxdasm/Sections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,39 @@ public PublicEntry this[int index]
}
}

public class SmxCalledFunctionsTable
{
private List<CalledFunctionEntry> functions_;

public SmxCalledFunctionsTable()
{
functions_ = new List<CalledFunctionEntry>();
}

public CalledFunctionEntry[] Entries
{
get { return functions_.ToArray(); }
}

public int Length
{
get { return functions_.Count; }
}

public CalledFunctionEntry this[int index]
{
get { return functions_[index]; }
}

public void AddFunction(uint addr)
{
var entry = new CalledFunctionEntry();
entry.Address = addr;
entry.Name = String.Format("sub_{0:x}", addr);
functions_.Add(entry);
}
}

// The .pubvars table.
public class SmxPubvarTable : SmxSection
{
Expand Down
10 changes: 10 additions & 0 deletions smxdasm/V1Disassembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ static V1Disassembler()
Prep(V1Opcode.ZERO_S, V1Param.Stack);
}

private SmxFile file_;
private byte[] data_;
private int code_start_;
private int proc_offset_;
Expand All @@ -205,6 +206,7 @@ private V1Opcode readNextOp()

private V1Disassembler(SmxFile file, SmxCodeV1Section code, int proc_offset)
{
file_ = file;
data_ = file.Header.Data;
code_start_ = code.CodeStart;
proc_offset_ = proc_offset;
Expand Down Expand Up @@ -247,6 +249,14 @@ private V1Instruction[] disassemble()
insn.Params = new int[insn.Info.Params.Length];
for (var i = 0; i < insn.Info.Params.Length; i++)
insn.Params[i] = readNext();

// Catch calls to unknown functions so they can be disassembled easily too.
if (op == (int)V1Opcode.CALL)
{
var addr = insn.Params[0];
if (file_.FindFunctionName(addr) == "(unknown)")
file_.CalledFunctions.AddFunction((uint)addr);
}
}
return insns.ToArray();
}
Expand Down
7 changes: 7 additions & 0 deletions smxdasm/V1Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ public static PublicEntry[] From(BinaryReader rd, SectionEntry header, SmxNameTa
}
}

// Called functions that weren't in the .publics or .dbg.symbols sections.
public class CalledFunctionEntry
{
public uint Address;
public string Name;
}

// The ".natives" section.
public class NativeEntry
{
Expand Down
7 changes: 7 additions & 0 deletions smxviewer/MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,13 @@ private void renderCodeSection(TreeNode root, SmxCodeV1Section code)
functionMap[sym.Name] = sym.CodeStart;
}
}
if (file_.CalledFunctions != null)
{
foreach (var fun in file_.CalledFunctions.Entries)
{
functionMap[fun.Name] = fun.Address;
}
}

foreach (var pair in functionMap)
{
Expand Down