diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/mapsorter | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/mapsorter')
| -rw-r--r-- | utils/mapsorter/Class1.cs | 30 | ||||
| -rw-r--r-- | utils/mapsorter/MapFileLoader.cs | 248 | ||||
| -rw-r--r-- | utils/mapsorter/MapSorter.csproj | 100 | ||||
| -rw-r--r-- | utils/mapsorter/MapSorter.exe | bin | 0 -> 20480 bytes | |||
| -rw-r--r-- | utils/mapsorter/MapSorter.sln | 21 |
5 files changed, 399 insertions, 0 deletions
diff --git a/utils/mapsorter/Class1.cs b/utils/mapsorter/Class1.cs new file mode 100644 index 0000000..40005d5 --- /dev/null +++ b/utils/mapsorter/Class1.cs @@ -0,0 +1,30 @@ +using System; +using System.Text.RegularExpressions; +using System.Collections; +using System.IO; + +namespace MapSorter +{ + + + /// <summary> + /// Summary description for Class1. + /// </summary> + class Class1 + { + /// <summary> + /// The main entry point for the application. + /// </summary> + [STAThread] + static void Main(string[] args) + { + if( args.Length != 1 ) + { + Console.WriteLine("Usage: MapSorter <filename.map>"); + return; + } + + new MapFileLoader(args[0]).DumpReport(); + } + } +} diff --git a/utils/mapsorter/MapFileLoader.cs b/utils/mapsorter/MapFileLoader.cs new file mode 100644 index 0000000..a77b194 --- /dev/null +++ b/utils/mapsorter/MapFileLoader.cs @@ -0,0 +1,248 @@ +using System; +using System.Text.RegularExpressions; +using System.Collections; +using System.IO; + +namespace MapSorter +{ + public class Element : IComparable + { + /// <summary> + /// Segment this element is in. + /// </summary> + public int Segment; + + /// <summary> + /// Base or virtual file address. + /// </summary> + public int Address; + + /// <summary> + /// Adjusted relative virtual address. + /// </summary> + public int RVA; + + /// <summary> + /// Name of this element. + /// </summary> + public string Text; + + /// <summary> + /// Object file this element is located in. + /// </summary> + public string Obj; + + /// <summary> + /// Size of this element, or -1. + /// </summary> + public int Size = -1; + + /// <summary> + /// True if this is the last element in an object file. + /// </summary> + public bool bCrossObj = false; + + public Element( int Segment, int Address, string Text, int RVA, string Obj ) + { + this.Segment = Segment; + this.Address = Address; + this.RVA = RVA; + this.Text = Text; + this.Obj = Obj; + } + + // Comparable interface: + int System.IComparable.CompareTo( object o ) + { + // HACK HACK - sorts according to size if size field is non negative, otherwise sorts by segment then address + Element other = (Element)o; + + // Sort by size: + if( other.Size != -1 || Size != -1 ) + { + if( Size < other.Size ) + return -1; + + if( Size > other.Size ) + return 1; + + return 0; + } + + // Sizes aren't defined, sort by Segment then Address: + if( Segment != other.Segment ) + { + if( Segment < other.Segment ) + return -1; + else + return 0; + } + + if( Address < other.Address ) + return -1; + else if( Address > other.Address ) + return 1; + + return 0; + } + } + + public class Module : IComparable + { + public string Name; + public int Size; + + public Module(string Name, int Size) + { + this.Name = Name; + this.Size = Size; + } + + int System.IComparable.CompareTo( object o ) + { + Module m = (Module)o; + if( Size < m.Size ) + return -1; + + if( Size > m.Size ) + return 1; + return 0; + } + } + + /// <summary> + /// An atomic class that loads and parses a given map file. + /// </summary> + public class MapFileLoader + { + ArrayList Elements; + ArrayList Modules; + + /// <summary> + /// Regular expression to break mapfile elements up: + /// </summary> + protected static Regex ElementRegex = new Regex(@"([0-9a-fA-F]{4})\:([0-9a-fA-F]{8})\s+([^\s]*)\s+([0-9a-fA-F]{8})\s(f\s)?(i\s)?\s+(.*\.obj)",RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase ); + + + public MapFileLoader( string filename ) + { + // Load the element data from the mapfile: + LoadElements( new StreamReader(filename).ReadToEnd() ); + + // Compute modules and their sizes: + ComputeModules(); + } + + public void DumpReport() + { + Console.WriteLine("***** Elements by size ascending. (*) = element straddles an .obj file boundary, so the size may not be correct."); + Console.WriteLine(); + + foreach (Element e in Elements ) + { + if( e.Size < 1024 ) + continue; + + if( e.bCrossObj ) + Console.Write("(*)"); + + Console.WriteLine( e.Size / 1024 + "k : " +e.Obj + " : " + e.Text ); + } + + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("***** Modules by size, ascending. This is estimated based on elements that don't straddle .obj boundaries."); + Console.WriteLine(); + + foreach(Module m in Modules ) + { + if( m.Size < 1024 ) + continue; + + Console.WriteLine( m.Size / 1024 + "k : " + m.Name ); + } + + + } + + protected void LoadElements( string mapfile ) + { + // Match each appropriate line in the map file. The summary entries at the top of each map file are NOT matched by this regex. + MatchCollection matches = ElementRegex.Matches(mapfile); + + + Elements = new ArrayList(); + + // Convert each match to an Element type and add them to an array list. + foreach( Match m in matches ) + { + + Element e = new Element(int.Parse(m.Groups[1].Value,System.Globalization.NumberStyles.AllowHexSpecifier), + int.Parse(m.Groups[2].Value,System.Globalization.NumberStyles.AllowHexSpecifier), + m.Groups[3].Value, + int.Parse(m.Groups[4].Value,System.Globalization.NumberStyles.AllowHexSpecifier), + m.Groups[7].Value); + + Elements.Add(e); + + } + + // Sort the list by address: + Elements.Sort(); + + Element previous = null; + + // Compute estimated sizes for each element in the list: + foreach( Element e in Elements ) + { + if( previous != null ) + { + if( e.Segment == previous.Segment ) + { + previous.Size = e.Address- previous.Address; + + // Take note of the symbols that cross object file boundaries: + if( !previous.Obj.Equals(e.Obj) ) + { + previous.bCrossObj = true; + } + } + } + + previous = e; + } + + // Sort the list by size + Elements.Sort(); + + + } + + protected void ComputeModules() + { + // Estimate the size of each object file: + Hashtable h = new Hashtable(); + + foreach(Element e in Elements ) + { + if( !h.ContainsKey(e.Obj) ) + h.Add(e.Obj,0); + + if( !e.bCrossObj ) + { + h[e.Obj] = (int)h[e.Obj] + e.Size; + } + } + + Modules = new ArrayList(); + + foreach( string key in h.Keys ) + { + Modules.Add( new Module(key, (int)h[key] )); + } + + Modules.Sort(); + } + + } +} diff --git a/utils/mapsorter/MapSorter.csproj b/utils/mapsorter/MapSorter.csproj new file mode 100644 index 0000000..c3e48c6 --- /dev/null +++ b/utils/mapsorter/MapSorter.csproj @@ -0,0 +1,100 @@ +<VisualStudioProject> + <CSHARP + ProjectType = "Local" + ProductVersion = "7.10.3077" + SchemaVersion = "2.0" + ProjectGuid = "{296D6B2D-4FAD-48BE-AC61-CEF53B472983}" + > + <Build> + <Settings + ApplicationIcon = "" + AssemblyKeyContainerName = "" + AssemblyName = "MapSorter" + AssemblyOriginatorKeyFile = "" + DefaultClientScript = "JScript" + DefaultHTMLPageLayout = "Grid" + DefaultTargetSchema = "IE50" + DelaySign = "false" + OutputType = "Exe" + PreBuildEvent = "" + PostBuildEvent = "" + RootNamespace = "MapSorter" + RunPostBuildEvent = "OnBuildSuccess" + StartupObject = "" + > + <Config + Name = "Debug" + AllowUnsafeBlocks = "false" + BaseAddress = "285212672" + CheckForOverflowUnderflow = "false" + ConfigurationOverrideFile = "" + DefineConstants = "DEBUG;TRACE" + DocumentationFile = "" + DebugSymbols = "true" + FileAlignment = "4096" + IncrementalBuild = "false" + NoStdLib = "false" + NoWarn = "" + Optimize = "false" + OutputPath = "bin\Debug\" + RegisterForComInterop = "false" + RemoveIntegerChecks = "false" + TreatWarningsAsErrors = "false" + WarningLevel = "4" + /> + <Config + Name = "Release" + AllowUnsafeBlocks = "false" + BaseAddress = "285212672" + CheckForOverflowUnderflow = "false" + ConfigurationOverrideFile = "" + DefineConstants = "TRACE" + DocumentationFile = "" + DebugSymbols = "false" + FileAlignment = "4096" + IncrementalBuild = "false" + NoStdLib = "false" + NoWarn = "" + Optimize = "true" + OutputPath = "bin\Release\" + RegisterForComInterop = "false" + RemoveIntegerChecks = "false" + TreatWarningsAsErrors = "false" + WarningLevel = "4" + /> + </Settings> + <References> + <Reference + Name = "System" + AssemblyName = "System" + HintPath = "..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll" + /> + <Reference + Name = "System.Data" + AssemblyName = "System.Data" + HintPath = "..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll" + /> + <Reference + Name = "System.XML" + AssemblyName = "System.Xml" + HintPath = "..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll" + /> + </References> + </Build> + <Files> + <Include> + <File + RelPath = "Class1.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "MapFileLoader.cs" + SubType = "Code" + BuildAction = "Compile" + /> + </Include> + </Files> + </CSHARP> +</VisualStudioProject> + diff --git a/utils/mapsorter/MapSorter.exe b/utils/mapsorter/MapSorter.exe Binary files differnew file mode 100644 index 0000000..d0b7e77 --- /dev/null +++ b/utils/mapsorter/MapSorter.exe diff --git a/utils/mapsorter/MapSorter.sln b/utils/mapsorter/MapSorter.sln new file mode 100644 index 0000000..be9b426 --- /dev/null +++ b/utils/mapsorter/MapSorter.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapSorter", "MapSorter.csproj", "{296D6B2D-4FAD-48BE-AC61-CEF53B472983}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {296D6B2D-4FAD-48BE-AC61-CEF53B472983}.Debug.ActiveCfg = Debug|.NET + {296D6B2D-4FAD-48BE-AC61-CEF53B472983}.Debug.Build.0 = Debug|.NET + {296D6B2D-4FAD-48BE-AC61-CEF53B472983}.Release.ActiveCfg = Release|.NET + {296D6B2D-4FAD-48BE-AC61-CEF53B472983}.Release.Build.0 = Release|.NET + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal |